improve of cmpl.
[bush.git] / tools / cmpl / shlib / toolchain.shlib
blob2b0ce3f777db818890a227519b7a06a8441c1e51
1 #!/bin/bash
2 ############################################################
3 # source: toolchain.shlib
4 # author: CottonCandyOwner(CottonCandyOwner@126.com)
5 # date: 2023-02-15
6 ############################################################
7 # note:
8 # toolchain cmd set. it uses fname.shlib to get output
9 # dirs, and ../platform/toolchain_info.imi for cmd name with
10 # cross compile prefix. before invoke func in this file, load
11 # parameters defined in dest/dest-xxx/* by param-load.shlib.
12 ############################################################
15 # todo:
16 # @ o2drv
17 # @ fhex2fbin/fbin2fhex
21 # features:
22 # @ absolution of toolchain cmd & op.
23 # !# cmd: gcc/ld/ar ...
24 # !# compile, asm2o(), c2o(), cpp2o(),
25 # !# link, o2exe(), o2a(), o2dlib(), o2drv()
26 # !# postage-proc, progstrip()
27 # !# postage-info, prog_size_info(), prog_symbols(), prog_func_symbs(),
28 # prog_var_symbs(), prog_inner_symbs(), prog_ext_symbs(),
29 # # postage-output, exe2bin(), exe2hex(), hex2bin(), bin2hex(),
30 # fhex2bin(), fbin2hex(),
31 # # general log output info, dbg output info.
32 # !@ compile hdr file dep list.
33 # !@ cross(untested)
34 # !@ different cpu arch optimzation opt.(untested)
35 # @ *opt check.
36 # @ gcc -f opt.
37 # @ INVOKE type
38 # @ prev & post invoke
42 # . incfile.shlib
45 # this func copied from incfile.shlib. due to the file is not in a fixed dir,
46 # it can'nt be used by source operation.
48 if test -z "$(type inc 2>/dev/null)"; then
49 inc ()
51 local tmp=$PWD
52 local ret=
54 test -z "$1" || test ! -f "$1" && return 1
56 tmp="$(echo "$1" | tr '[[:punct:]]' '_')"
57 eval test "\${$tmp}" = 1 && return 0
58 eval $tmp=1
60 cd $(dirname $1)
61 source $(basename $1)
62 ret=$?
63 cd $tmp
65 return $ret
70 inc porting.shlib
72 # file name format define
73 # before using,
75 inc fname.shlib
79 ######################
80 # section: common comment info
81 ######################
83 ######################
84 # section: variable define
85 ######################
89 ######################
90 # section: private function
91 ######################
93 toolchain_dbgout ()
95 test "${OPT_VERBOSE_INFO}" = 'Y' -o "${OPT_VERBOSE_INFO}" = 'y' && echo "$@"
96 return;
97 echo "$@"
102 ######################
103 # section: public function
104 ######################
106 #########################################
107 # Compile Function
108 #########################################
110 # OPT_OBJSIZE_INFO=Y
111 # OPT_VERBOSE_INFO=Y
112 # OPT_DEPHDR=Y
113 # OPT_CALL_GRAPH=Y
115 cmd_run ()
117 local cmd="$1"
118 local output=
119 local ret=
120 local line=
121 CMD_BAK=$cmd
123 # attention -lncurses paramter must be put after .o file,
124 # or it report err that symbol not found.
125 # cmd="${CC} ${ASFLAGS_OUT} ${ASFLAGS_EXT} ${CFLAGS} ${LDFLAGS} $(envar ${SRC_FILE[@]}) -o ${DST_FILE[0]}"
128 # XXX: if there is blank in quoted "string", it will be shorten to single.
129 # append '\' before it.
131 cmd="$(echo "${cmd}" | tr -s '[[:space:]]' ' ')"
133 # release var after cmd is filled.
134 unsetenv SRC_FILE
135 unsetenv DST_FILE
138 # TBD: do parameter checking work here.
142 # build operation
143 # NOTE:
144 # if stdout is redirected by '|' pipe,
145 # it will not display with color.
147 # output="$( eval $cmd 2>&1 )"
148 eval $cmd > /tmp/output.log 2>&1
149 ret=$?
151 echo -ne " === ${cmd}\n" >> ${OUTDIR}/build-dbgout.log
152 echo -ne " === ${cmd}\n" >> ${OUTDIR}/build.log
153 # echo -ne " === ${cmd}\n" >&2
155 if test $ret = 0 || ! test -s /tmp/output.log && test "${verbose_mode}" != Y -a "${verbose_mode}" != y ; then
156 toolchain_dbgout -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
157 else
158 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
159 cat /tmp/output.log
160 test "${OPT_VERBOSE_INFO}" = 'Y' -o "${OPT_VERBOSE_INFO}" = 'y' && cat /tmp/output.log >> ${OUTDIR}/build-dbgout.log
163 test "$ret" != 0 && return 2
164 return 0
168 # fsyntax: asm2o <src-file> <output-file>
169 # fdesc: asm汇编程序.S文件编译成.o文件。
171 asm2o ()
173 local cmd=
175 test -n "${1}" && SRC_FILE="$1"
176 test -n "${2}" && setenv DST_FILE[1]="$2"
178 eval cmd=\"$ASM2O_CMD_FMT\"
179 cmd_run "$cmd"
180 cmd=$?
182 test $cmd = 0 && CMPL_OBJ_LIST="$CMPL_OBJ_LIST $fdst"
183 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
185 return $cmd
189 # fsyntax: src2dst_filename
190 # fdesc: compile each src file.
192 src2dst_filename ()
194 test -z "${SRC_FILE}" && echo -e "[error]: SRC_FILE[0] should not be NULL, and '\n$(decl -p DST_FILE)'.\n" >&2 && exit
196 local tmp="$(echo "$SRC_FILE" | sed -E "s/,.*\$//g")"
197 SRC_FILE="$(echo "$SRC_FILE" | sed -E "s/\,/\ /g")"
199 test -z "${DST_FILE}" && fname_src2dst $tmp
200 test -z "$(getenv DST_FILE[1])" && fname_src2obj $tmp
202 if test "$OPT_DEPHDR" = 'Y' -o "$OPT_DEPHDR" = 'y' -o "$OPT_CALLGRAPH" = 'Y' -o "$OPT_CALLGRAPH" = 'y'; then
203 test -z "$(getenv DST_FILE[2])" && fname_src2dep $tmp
204 test -z "$(getenv DST_FILE[3])" && fname_src2graph $tmp
209 # set those two by cmd opt or envar or DEBUG/RELEASE opt.
211 # OPT_DEPHDR
212 # OPT_CALLGRAPH
215 # fsyntax: c2o <src-file> [ <obj-file> [ <dep-file> [<graph-file>] ] ]
216 # fdesc: .c src file compile to .o file. parameters can be given in func arg,
217 # and envar SRC_FILE & DST_FILE. you can given one param <obj-file> only,
218 # it will generate others in auto.
220 cmpl_src ()
222 local lang=$1
223 local LANG=$2
224 local DST=$3
225 local cmd=
226 local fdst=
227 shift 3
229 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[$lang])$ && SRC_FILE="$1"
230 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[obj])$ && setenv DST_FILE[1]="$2"
231 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[exe])$ && DST_FILE="$2"
232 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
233 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
234 src2dst_filename
235 fdst="$(getenv DST_FILE[1]) "
237 mkdir -p $(dirname $(getenv DST_FILE[1]))
239 # echo \$1=${1}
240 # echo \$2=${2}
241 # echo SRC_FILE=$(envar SRC_FILE[@])
242 # echo DST_FILE=$(envar DST_FILE[@])
244 CFLAGS_DEPHDR_Y=""
245 CFLAGS_CALLGRAPH_Y=""
246 if test -n "$(getenv DST_FILE[2])" && test "${OPT_DEPHDR}" = 'Y' -o "${OPT_DEPHDR}" = 'y'; then
247 eval "CFLAGS_DEPHDR_Y=\"$CFLAGS_DEPHDR_Y_EVL\""
249 if test -n "$(getenv DST_FILE[3])" && test "${OPT_CALL_GRAPH}" = 'Y' -o "${OPT_CALL_GRAPH}" = 'y'; then
250 eval "CFLAGS_CALLGRAPH_Y=\"$CFLAGS_CALLGRAPH_Y_EVL\""
253 eval cmd=\"\${${LANG}2${DST}_CMD_FMT}\"
254 eval cmd=\"${cmd}\"
255 cmd_run "$cmd"
256 cmd=$?
258 test $cmd = 0 && CMPL_OBJ_LIST="$CMPL_OBJ_LIST $fdst"
259 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
261 return $cmd
264 c2o ()
266 cmpl_src c C O $@
267 return $?
271 # fsyntax: cxx2o
272 # fdesc: .cc文件编译成.o文件。
273 cxx2o ()
275 local cmd=
276 local fdst=
278 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[cxx])$ && setenv SRC_FILE="$1"
279 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[obj])$ && setenv DST_FILE[1]="$2"
280 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
281 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
282 src2dst_filename
283 fdst="$(getenv DST_FILE[1]) "
285 mkdir -p $(dirname $(getenv DST_FILE[0]))
287 CFLAGS_DEPHDR_Y=""
288 CFLAGS_CALLGRAPH_Y=""
289 if test -n "$(getenv DST_FILE[2])" && test "${OPT_DEPHDR}" = 'Y' -o "${OPT_DEPHDR}" = 'y'; then
290 eval "CFLAGS_DEPHDR_Y=\"$CFLAGS_DEPHDR_Y_EVL\""
292 if test -n "$(getenv DST_FILE[3])" && test "${OPT_CALL_GRAPH}" = 'Y' -o "${OPT_CALL_GRAPH}" = 'y'; then
293 eval "CFLAGS_CALLGRAPH_Y=\"$CFLAGS_CALLGRAPH_Y_EVL\""
296 eval cmd=\"$CXX2O_CMD_FMT\"
297 cmd_run "$cmd"
298 cmd=$?
300 test $cmd = 0 && CMPL_OBJ_LIST="$CMPL_OBJ_LIST $fdst"
301 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
303 return $cmd
307 # fsyntax: cpp2o
308 # fdesc: cpp程序.cpp文件编译成.o文件。
310 cpp2o ()
312 local cmd=
313 local fdst=
315 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[cpp])$ && SRC_FILE="$1"
316 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[obj])$ && setenv DST_FILE[1]="$2"
317 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
318 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
319 src2dst_filename
320 fdst="$(getenv DST_FILE[1]) "
322 mkdir -p $(dirname ${DST_FILE})
324 CFLAGS_DEPHDR_Y=""
325 CFLAGS_CALLGRAPH_Y=""
326 if test -n "$(getenv DST_FILE[2])" && test "${OPT_DEPHDR}" = 'Y' -o "${OPT_DEPHDR}" = 'y'; then
327 eval "CFLAGS_DEPHDR_Y=\"$CFLAGS_DEPHDR_Y_EVL\""
329 if test -n "$(getenv DST_FILE[3])" && test "${OPT_CALL_GRAPH}" = 'Y' -o "${OPT_CALL_GRAPH}" = 'y'; then
330 eval "CFLAGS_CALLGRAPH_Y=\"$CFLAGS_CALLGRAPH_Y_EVL\""
333 eval cmd=\"$CPP2O_CMD_FMT\"
334 cmd_run "$cmd"
335 cmd=$?
337 test $cmd = 0 && CMPL_OBJ_LIST="$CMPL_OBJ_LIST $fdst"
338 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
340 return $cmd
345 # fsyntax: asm2exe
346 # fdesc: .asm文件编译成exe文件。
347 asm2exe ()
349 local cmd=
351 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[asm])$ && SRC_FILE="$1"
352 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[obj])$ && setenv DST_FILE[1]="$2"
353 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
354 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
355 src2dst_filename
357 mkdir -p $(dirname ${DST_FILE})
359 eval cmd=\"$ASM2EXE_CMD_FMT\"
360 cmd_run "$cmd"
361 cmd=$?
363 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
365 return $cmd
369 # fsyntax: c2exe
370 # fdesc: c语言程序.c文件编译成.o文件。
371 c2exe ()
373 cmpl_src c C EXE $@
374 return $?
378 # fsyntax: cxx2exe
379 # fdesc: cpp程序.cpp文件编译成.o文件。
381 cxx2exe ()
383 local cmd=
385 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[cxx])$ && SRC_FILE="$1"
386 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[obj])$ && DST_FILE="$2"
387 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
388 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
389 src2dst_filename
391 mkdir -p $(dirname ${DST_FILE})
393 eval cmd=\"$CXX2EXE_CMD_FMT\"
394 cmd_run "$cmd"
395 cmd=$?
397 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
399 return $cmd
403 # fsyntax: cpp2exe
404 # fdesc: cpp程序.cpp文件编译成.o文件。
406 cpp2exe ()
408 local cmd=
410 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[cpp])$ && SRC_FILE="$1"
411 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[obj])$ && setenv DST_FILE[1]="$2"
412 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
413 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
414 src2dst_filename
416 mkdir -p $(dirname ${DST_FILE})
418 eval cmd=\"$CPP2EXE_CMD_FMT\"
419 cmd_run "$cmd"
420 cmd=$?
422 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
424 return $cmd
428 #########################################
429 # link function
430 #########################################
433 # fsyntax: o2o
434 # fdesc: .o文件链接成.o文件。
436 o2o ()
438 local cmd=
440 test -n "${1}" && SRC_FILE="$1"
441 test -n "${2}" && DST_FILE="$2"
442 test -n "${3}" && setenv DST_FILE[2]="$3"
443 test -n "${4}" && setenv DST_FILE[3]="$4"
444 src2dst_filename
446 mkdir -p $(dirname ${DST_FILE})
448 eval cmd=\"$O2O_CMD_FMT\"
449 cmd_run "$cmd"
450 cmd=$?
452 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
454 return $cmd
458 # fsyntax: link_filename_fix
459 # fdesc: compile each src file.
461 link_filename_fix ()
463 local ext=
464 local dst=
465 local file=
467 # eval "ext=\"\${LANG_EXT_NAME[${lang,,}]}\""
468 #"${SRC_FILE##*.}"
470 # obj="${DSTDIR}/${obj//\.$ext/\.o}"
471 # DST_FILE="${DSTDIR}/${DST_FILE}"
473 fname_objdir
474 for file in $(arrname SRC_FILE); do
475 if [[ ! "$(eval echo "\"\${$file}\"")" =~ ${OBJDIR} ]]; then
476 setenv $file="${OBJDIR}/$(eval echo -n "\"\${$file}\"")"
478 done
479 # DST_FILE[0]="${OUTDIR}/${DST_FILE[0]}"
483 # fsyntax: o2lib
484 # fdesc: .o files link to static library.
486 link_dest ()
488 local src=$1
489 local SRC=$2
490 local dst=$3
491 local DST=$4
492 local cmd=
493 local output=
494 local ret=
495 local file=
496 shift 4
498 # test -n "${1}" && strstr "${!1}" =~ $(getenv EXT_NAME[$src])$ && eval SRC_FILE=\"\${$1}\"
499 # XXX: if $dst = exe in windows, it matched every time due to no sfx name.
500 # test -n "${2}" && strstr "${!2}" =~ $(getenv EXT_NAME[$dst])$ && DST_FILE="$2"
501 link_filename_fix
503 # echo \$2=$2=${!2}
504 # echo DST_FILE=$DST_FILE
506 file=${DST_FILE}
507 mkdir -p $(dirname ${DST_FILE})
509 eval cmd=\"\${${SRC}2${DST}_CMD_FMT}\"
510 eval cmd=\"$cmd\"
511 cmd_run "$cmd"
512 cmd=$?
513 # test $? != 0 && return $?
515 DST_FILE="$file"
517 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} ${DST_FILE}
519 return $cmd
523 # fsyntax: o2lib
524 # fdesc: .o files link to static library.
526 o2lib ()
528 local ret=
530 link_dest obj O lib LIB $@
531 ret=$?
532 test "$ret" != 0 && return $ret
534 ranlib $DST_FILE
535 return $?
539 # fsyntax: o2la
540 # fdesc: .o files link to general static library.
542 o2la ()
544 # TBD:
545 # if test $ret != 0 ; then
546 return 2
547 # else
548 # return 0
549 # fi
553 # fsyntax: o2dll
554 # fdesc: .o files link to dynamic library.
556 o2dll ()
558 local cmd=
560 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[obj])$ && SRC_FILE="$1"
561 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[dll])$ && setenv DST_FILE[1]="$2"
562 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
563 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
564 link_filename_fix
566 mkdir -p $(dirname ${DST_FILE})
568 eval cmd=\"$O2DLL_CMD_FMT\"
569 cmd_run "$cmd"
570 cmd=$?
572 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
574 return $cmd
578 # fsyntax: o2libdll
579 # fdesc: .o files link to static & dynamic library.
581 o2libdll ()
583 local cmd=
584 local output=
585 local ret=
586 local file=
587 local srcfile=
589 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[obj])$ && SRC_FILE="$1"
590 test -n "${2}" && strstr "${2}" =~ \($(getenv EXT_NAME[lib])|$(getenv EXT_NAME[dll])\)$ && setenv DST_FILE[1]="$2"
591 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
592 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
593 link_filename_fix
595 mkdir -p $(dirname ${DST_FILE})
597 file=$DST_FILE
598 loadarr srcfile = "( $(envar SRC_FILE[@]) )"
599 DST_FILE="$(echo "${DST_FILE}" | sed -E "s/\.[^\.]*/.a/g")"
601 eval cmd=\"$O2LIB_CMD_FMT\"
602 cmd_run "$cmd"
603 test $? != 0 && return $?
605 ${RANLIB} ${file}
606 test $? != 0 && return $?
608 loadarr SRC_FILE = "( $(envar srcfile[@]) )"
609 DST_FILE="$(echo "${DST_FILE}" | sed -E "s/\.[^\.]*/.so/g")"
611 eval cmd=\"$O2DLL_CMD_FMT\"
612 cmd_run "$cmd"
613 cmd=$?
615 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
617 return $cmd
621 # fsyntax: o2exe
622 # fdesc: .o files link to executables.
624 o2exe ()
626 local cmd=
627 local file=
629 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[obj])$ && SRC_FILE="$1"
630 # test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[exe])$ && DST_FILE="$2"
631 # test -n "${2}" && strstr "${2}" =~ \($(getenv EXT_NAME[lib])|$(getenv EXT_NAME[dll])\)$ &&
632 # DST_FILE="$(eval echo "\"\${$2}\"")"
633 link_filename_fix
635 file=${DST_FILE}
636 mkdir -p $(dirname ${DST_FILE})
638 eval cmd=\"$O2EXE_CMD_FMT\"
639 cmd_run "$cmd"
640 cmd=$?
642 DST_FILE="$file"
644 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
646 return $cmd
650 # fsyntax: o2drv
651 # fdesc: .o文件链接成elf格式linux的drv文件。
653 o2drv ()
655 local cmd=
657 test -n "${1}" && strstr "${1}" =~ $(getenv EXT_NAME[obj])$ && SRC_FILE="$1"
658 test -n "${2}" && strstr "${2}" =~ $(getenv EXT_NAME[drv])$ && setenv DST_FILE[1]="$2"
659 test -n "${3}" && strstr "${3}" =~ \.dephdr$ && setenv DST_FILE[2]="$3"
660 test -n "${4}" && strstr "${4}" =~ \.cgraph$ && setenv DST_FILE[3]="$4"
661 link_filename_fix
663 mkdir -p $(dirname ${DST_FILE})
665 eval cmd=\"$O2DRV_CMD_FMT\"
666 cmd_run "$cmd"
667 cmd=$?
669 test "${OPT_OBJSIZE_INFO}" = 'Y' -o "${OPT_OBJSIZE_INFO}" = 'y' && eval ${SIZE} $(getenv DST_FILE[1])
671 return $cmd
674 #########################################
675 # build postage processing & info.
676 # size of .text/.data/.rodata/.bss.
677 # internal symbol of an executable file.
678 # export symbol of an executable file.
681 # nm -D <file>, dynamic symbol. U, imported; T, exported.
682 # nm -g <file>, global symbol, all symbol.
684 # objdump -t <file> | grep -e "\.text", native code symbol.
685 # objdump -t <file> | grep -e "\.data", initialized var symbol.
686 # objdump -t <file> | grep -e "\.rodata", read only var symbol.
687 # objdump -t <file> | grep -e "\.bss", uninitialized var symbol.
689 # size <file>, it display size info in .text/.data(.rodata)/.bss
690 #########################################
693 # fsyntax: progstrip
694 # fdesc: delete debug symbol info .etc .
696 progstrip ()
698 local cmd=
699 local output=
700 local ret=
702 test -n "${2}" || test -n "$DST_FILE" && DST_FILE="${OUTDIR}/$2"
704 # attention -lncurses paramter must be put after .o file,
705 # or it report err that symbol not found.
706 cmd="${STRIP} $(envar DST_FILE[@])"
708 toolchain_dbgout -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
710 # build operation
711 output="$( eval $cmd 2>&1; )"
712 ret=$?
714 echo -ne " === ${cmd}\n" >> ${OUTDIR}/build-dbgout.log
715 echo -ne " === ${cmd}\n" >> ${OUTDIR}/build.log
717 if test $ret == 0 || test -z "$output" ; then
718 toolchain_dbgout -ne " === ${cmd}\n"
719 else
720 toolchain_dbgout -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
721 toolchain_dbgout "$output"
722 echo "$output" >> ${OUTDIR}/build-dbgout.log
725 if test $ret != 0 ; then
726 return 2
727 else
728 return 0
733 # fsyntax: prog_sizeinfo
734 # fdesc: size of .text/.data/.rodata/.bss.
736 prog_sizeinfo ()
738 local cmd=
739 local output=
740 local ret=
741 local file=
742 local filelist=
744 test -z "$DST_FILE" && eval DST_FILE="${OUTDIR}/\${${3}}"
745 fname_dstdir
747 # attention -lncurses paramter must be put after .o file,
748 # or it report err that symbol not found.
749 cmd="${SIZE} $(basename ${DST_FILE})"
751 toolchain_dbgout -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
753 # build operation
754 cd $(dirname ${DST_FILE})
755 output="$( eval ${cmd} 2>&1; )"
756 ret=$?
757 cd - 2>&1 >/dev/null
759 echo -ne " === ${cmd}\n" >> ${OUTDIR}/build-dbgout.log
760 echo -ne " === ${cmd}\n" >> ${OUTDIR}/build.log
762 if test $ret == 0 || test -z "$output" ; then
763 toolchain_dbgout -ne " === ${cmd}\n"
764 infoo "$output"
765 else
766 toolchain_dbgout -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
767 infoo "$output"
768 echo "$output" >> ${OUTDIR}/build-dbgout.log
771 if test $ret != 0 ; then
772 return 2
773 else
774 return 0
779 # fsyntax: prog_symboals
780 # fdesc: output .text/.data/.rodata/.bss symbols in executables.
782 prog_symboals ()
784 local ret=
785 local file=
787 while read file; do
788 toolchain_dbgout "[$file]"
789 { ${OBJDUMP} -t $file; ret=$?; } | grep -o -e "\*UND\*.*" -e "\.bss.*" -e "\.rodata.*" -e "\.data.*" -e "\.text.*" | grep -v $'[ |\t]'"\..*" | grep -v \"00000000\" | sort | sed -e "s/\.text/func-i/g; s/\*UND\*/func-e/g; s/\.data/var-i/g; s/\.bss/var/g; s/\.rodata/var-e/g;"
790 test $ret != 0 && break;
791 done << EOF
792 $(envar SRC_FILE[@])
795 if test $ret != 0 ; then
796 return 2
797 else
798 return 0
802 SYMB_FILTER_SYS='y'
805 # fsyntax: prog_inner_symbs
806 # fdesc: output internal symbols in executables.
808 prog_inner_symbs ()
810 local ret=
811 local file=
812 local param=
814 test $SYMB_FILTER_SYS = 'y' && param="-v \"00000000\""
816 while read file; do
817 toolchain_dbgout "[$file]"
818 { ${OBJDUMP} -t $file; ret=$?; } | grep -o -e "\.text.*"| grep -v $'[ |\t]'"\..*" | sort | sed -e "s/\.text/func-i/g;"
819 done << EOF
820 $(envar SRC_FILE[@])
823 if test $ret != 0 ; then
824 return 2
825 else
826 return 0
831 # fsyntax: prog_ext_symbs
832 # fdesc: output external symbols in executables.
834 prog_ext_symbs ()
836 local ret=
837 local file=
839 while read file; do
840 toolchain_dbgout "[$file]"
841 { ${OBJDUMP} -t $file; ret=$?; } | grep -o -e "\*UND\*.*"| grep -v $'[ |\t]'"\..*" | grep -v \"00000000\" | sort | sed -e "s/\*UND\*/func-e/g;;"
842 done << EOF
843 $(envar SRC_FILE[@])
846 if test $ret != 0 ; then
847 return 2
848 else
849 return 0
854 # fsyntax: prog_func_symbs
855 # fdesc: output function symbols in executables.
857 prog_func_symbs ()
859 local ret=
860 local file=
862 while read file; do
863 toolchain_dbgout "[$file]"
864 { ${OBJDUMP} -t $file; ret=$?; } | grep -o -e "\*UND\*.*" -e "\.text.*" | grep -v $'[ |\t]'"\..*" | sort | sed -e "s/\.text/func-i/g; s/\*UND\*/func-e/g;"
865 done << EOF
866 $(envar SRC_FILE[@])
869 if test $ret != 0 ; then
870 return 2
871 else
872 return 0
877 # fsyntax: prog_func_symbs
878 # fdesc: output function symbols in executables.
880 prog_var_symbs ()
882 local ret=
883 local file=
885 while read file; do
886 toolchain_dbgout "[$file]"
887 { ${OBJDUMP} -t $file; ret=$?; } | grep -o -e "\.bss.*" -e "\.rodata.*" -e "\.data.*" | grep -v $'[ |\t]'"\..*" | grep -v \"00000000\" | sort | sed -e "s/\.text/func-i/g; s/\*UND\*/func-e/g;"
888 done << EOF
889 $(envar SRC_FILE[@])
892 if test $ret != 0 ; then
893 return 2
894 else
895 return 0
900 #########################################
901 # bin/hex output and transform.
902 #########################################
906 # fsyntax: exe2hex
907 # fdesc: bin二进制文件转换成hex字符串。
909 exe2hex ()
911 exe2bin "$@"
912 bin2hex "$@"
916 # fsyntax: exe2bin
917 # fdesc: elf文件读取code/data的section,保存成bin文件。
918 # 通常用于非操作系统环境下运行的程序。
920 exe2bin ()
922 local ret=
924 { objcopy -t $file | grep -o -e "\.bss.*" -e "\.rodata.*" -e "\.data.*"; ret=$?; } | grep -v $'[ |\t]'"\..*" | grep -v \"00000000\" | sort | sed -e "s/\.text/func-i/g; s/\*UND\*/func-e/g;"
926 if test $ret != 0 ; then
927 return 2
928 else
929 return 0
934 # fsyntax: bin2hex
935 # fdesc: bin二进制文件转换成hex字符串。
937 bin2hex ()
939 # hexdump -e '/1 "%02x " '
940 xxd -ps -c 16 - 2>/dev/null
944 # fsyntax: hex2bin
945 # fdesc: hex字符串转换成bin二进制数据文件。
947 hex2bin ()
949 xxd -r - $2
953 # fsyntax: fbin2fhex <srcfile> <dst>
954 # fdesc: bin二进制文件转换成hex文件。
956 fbin2fhex ()
958 xxd -ps -c 16 $1 2>/dev/null > $2
962 # fsyntax: fhex2fbin
963 # fdesc: hex文件转换成bin二进制数据文件。
965 fhex2fbin ()
967 xxd -r $1 > $1
971 # or use ':'
973 nullcmd ()
975 echo "[error]: cmd not defined. look at the defination in toolchain/${TOOLCHAIN}.imi, or use another toolchain." >&2
976 exit -1
979 # syntax: without_pfx <pfx>
980 without_pfx ()
982 local name=
983 eval local varlist="\${!${1}*}"
985 for var in ${varlist}; do
986 eval name="\${var#$1}"
987 eval $name=${!var}
988 # TBD:
989 # name="$(echo "$var" | sed -E "s/$1//g"}"
990 # eval $name=\"\${$var}\"
991 done
995 # fdesc: get
999 # fdesc: get
1001 get_toolchain_info ()
1003 echo 'int main(){}' > /tmp/dummy.c
1005 verbose_mode=y
1007 # test the parameters setting in files.
1008 # use c2exe() instead of directly invoke, it can test for some 'GCC' cross-compiler.
1010 # gcc /tmp/dummy.c -I. -L/tmp/lib -Wl,-rpath,/tmp/lib -rdynamic -lpthread -v -Wl,--verbose &> /tmp/dummy.log
1011 LDFLAGS_EXT="-v -Wl,--verbose -lpthread" c2exe /tmp/dummy.c /tmp/dummy > /tmp/dummy.log
1012 test $? != 0 && echo "compile src in get_toolchain_info() error." >&2 && echo CMD_BAK=\"$CMD_BAK\" && cat /tmp/dummy.log && exit
1013 unset verbose_mode
1016 # get include paths for '#include <...>'
1018 # echo "===== get include path ====="
1019 loadarr INC_PATHS = "( `grep -B100 '^End of search list.' /tmp/dummy.log | grep -A100 '^#include <...>' | grep -v 'End of search list.' | grep -v '#include <...>'` )"
1020 # echo INC_PATHS:
1021 # envar INC_PATHS[@]
1023 # /usr/lib/gcc/i686-linux-gnu/5/include
1024 # /usr/local/include
1025 # /usr/lib/gcc/i686-linux-gnu/5/include-fixed
1026 # /usr/include/i386-linux-gnu
1027 # /usr/include
1030 # get lib paths in linking
1032 # echo "===== get lib path ====="
1033 loadarr LIB_PATHS = "( `grep 'SEARCH.*/usr/lib' /tmp/dummy.log |sed 's|; |\n|g' | sed 's|SEARCH_DIR("=||g' | sed 's|")||g' | sed 's|;||g'` )"
1034 # echo LIB_PATHS:
1035 # envar LIB_PATHS[@]
1036 #/usr/local/lib/i386-linux-gnu
1037 #/lib/i386-linux-gnu
1038 #/usr/lib/i386-linux-gnu
1039 #/usr/local/lib32
1040 #/lib32
1041 #/usr/lib32
1042 #/usr/local/lib
1043 #/lib
1044 #/usr/lib
1045 #/usr/i686-linux-gnu/lib32
1046 #/usr/i686-linux-gnu/lib
1049 # get lib libpthread linked in.
1051 # echo "===== get libs ====="
1052 loadarr LINKED_LIBS = "( `grep -e 'succeeded' /tmp/dummy.log | grep -v '\.o[[:blank:]]*' | sed 's|attempt to open ||g' | sed 's| succeeded||g' | xargs file -L 2>/dev/null| grep -E 'ELF|archive' | sed 's|:.*$||g'` )"
1053 # echo LINKED_LIBS:
1054 # envar LINKED_LIBS[@]
1055 #/lib/i386-linux-gnu/libpthread.so.0
1056 #/usr/lib/i386-linux-gnu/libpthread_nonshared.a
1058 rm /tmp/dummy.c /tmp/dummy /tmp/dummy.log -f
1061 cmplr_ver ()
1063 $1 -v 2>&1 | grep -oE "^gcc version [[:alnum:]_+.-]+ " | sed -E "s/^gcc version ([[:alnum:]_+.-]+) /\1/g"
1068 ######################
1069 # section: file tail
1070 ######################
1072 return 0
1076 # fsyntax: toolchain_chk
1077 # fdesc: check toolchain if it can works in usual. save flags in
1078 # cmpl config file.
1080 toolchain_chk ()
1082 # TBD:
1087 # fsyntax: dev_env_chk
1088 # fdesc: check commands and build env.
1090 dev_env_chk ()
1092 # TBD:
1097 # fsyntax: dep_lib_chk
1098 # fdesc: check external lib file if it exist and can works.
1099 # save checking resualt into cmpl config file.
1101 dep_lib_chk ()
1103 # TBD:
1108 # fsyntax: dep_syshdr_chk
1109 # fdesc: check system .h file if it exist.
1111 dep_syshdr_chk ()
1113 # TBD: