20230310
[build-config.git] / build / shlib / toolchain.shlib
blob8b82b551ac49678127932bb67f3ecfc15f4f704f
1 #!/bin/bash
2 ############################################################
3 # source: toolchain.shlib
4 # author: devenkong(18151155@qq.com)
5 # date: 2022-04-21
6 ############################################################
7 # note:
8 # 编译器工具链相关的函数集。
9 ############################################################
12 # todo:
13 # @
14 # @
18 # features:
19 # @ toolchain cmd & op absolution.
20 # !# cmd: gcc/ld/ar ...
21 # !# compile, asm2o(), c2o(), cpp2o(),
22 # !# link, o2exe(), o2a(), o2dlib(), o2drv()
23 # !# postage-proc, progstrip()
24 # !# postage-info, prog_size_info(), prog_symbols(), prog_func_symbs(),
25 # prog_var_symbs(), prog_inner_symbs(), prog_ext_symbs(),
26 # # postage-output, exe2bin(), exe2hex(), hex2bin(), bin2hex(),
27 # fhex2bin(), fbin2hex(),
28 # # general log output info, dbg output info.
29 # @ cross
30 # @ different cpu arch optimzation opt.
31 # @ *opt check.
32 # @ compile hdr file dep list.
33 # @ gcc -f opt.
34 # @ INVOKE type
35 # @ prev & post invoke
38 . shlibinc
40 include gplib.shlib
42 include stdio.shlib
43 include term.shlib
45 ######################
46 # section: common comment info
47 ######################
49 ######################
50 # section: variable define
51 ######################
53 # just use GNU, or append gcc version
54 CPLR_NAME=GNU
56 TARGET=""
57 SYSTEM=""
58 XXX=""
61 # define cmd which name is different from it in TOOLCHAIN_LIST.
62 # CPLR_NAME is the toolchain name. or it can be defined directly
63 # by using ${CPLR_NAME}.
65 declare -g ${CPLR_NAME}_CC="gcc"
66 declare -g ${CPLR_NAME}_CXX="gcc"
67 declare -g ${CPLR_NAME}_CPP="g++"
68 declare -g ${CPLR_NAME}_LINK="gcc"
69 declare -g ${CPLR_NAME}_FORTRAN="gfortran"
72 TOOLCHAIN_PROG_LIST=''
73 TOOLCHAIN_VAR_LIST=''
74 TOOLCHAIN_LIST='
76 CXX
77 CPP
80 FORTRAN
81 RANLIB
82 LINK
84 GCONV
85 GPROF
87 OBJCOPY
88 OBJDUMP
89 READELF
90 STRIP
91 ADDR2LINE
92 SIZE'
95 LINK=''
97 CCFLAGS_CALLGRAPH_EVL=" -fcallgraph-info=${DST_FILE[2]} "
99 CCFLAGS_DEPHDR_EVL=' -MT ${DST_FILE[0]} -MD -MP -MF ${DST_FILE[1]} '
100 #CCFLAGS_DEPHDRHDR_EVL=' -MM -MT ${DST_FILE[0]} -MF ${DST_FILE[1]} '
101 #CCFLAGS_DEPHDRHDR_EVL=' -MM -MT ${DST_FILE} -MF ${SRC_FILE//.c[p]?[p]?/.dep} '
102 #CCFLAGS_DEPHDRHDR_EVL=' -MT "$object" -MD -MP -MF "$tmpdepfile"'
104 # it uses this paramter in depcomp
105 # -MT "$object" -MD -MP -MF "$tmpdepfile"
108 ######################
109 # section: private function
110 ######################
114 # fsyntax: src2dst_filename
115 # fdesc: compile each src file.
117 src2dst_filename ()
119 local ext=
120 local dst=
121 ext="${SRC_FILE[0]##*.}"
123 obj="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${obj//\.$ext/\.o}"
125 DST_FILE[0]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${SRC_FILE[0]//\.$ext/\.o}"
126 DST_FILE[1]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${SRC_FILE[0]//\.$ext/\.dep}"
127 SRC_FILE[0]="${SRCPKG_TOPDIR}/${SRC_FILE[0]}"
132 #############################################################################
133 # compile with dep info
134 # copy code directly from build-aux/depcomp.
136 ############################################################################
139 source=
140 object=
141 depfile=
142 tmpldepfile=
143 DEPDIR=
146 # A tabulation character.
147 tab=' '
148 # A newline character.
149 nl='
151 # Character ranges might be problematic outside the C locale.
152 # These definitions help.
153 upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
154 lower=abcdefghijklmnopqrstuvwxyz
155 digits=0123456789
156 alpha=${upper}${lower}
158 COMPILE=gcc_compile
161 gcc_compile_elder ()
163 ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
164 ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
165 ## (see the conditional assignment to $gccflag above).
166 ## There are various ways to get dependency output from gcc. Here's
167 ## why we pick this rather obscure method:
168 ## - Don't want to use -MD because we'd like the dependencies to end
169 ## up in a subdir. Having to rename by hand is ugly.
170 ## (We might end up doing this anyway to support other compilers.)
171 ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
172 ## -MM, not -M (despite what the docs say). Also, it might not be
173 ## supported by the other compilers which use the 'gcc' depmode.
174 ## - Using -M directly means running the compiler twice (even worse
175 ## than renaming).
176 if test -z "$gccflag"; then
177 gccflag=-MD,
179 "$@" -Wp,"$gccflag$tmpdepfile"
180 stat=$?
181 if test $stat -ne 0; then
182 rm -f "$tmpdepfile"
183 exit $stat
185 rm -f "$depfile"
186 echo "$object : \\" > "$depfile"
187 # The second -e expression handles DOS-style file names with drive
188 # letters.
189 sed -e 's/^[^:]*: / /' \
190 -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
192 ## This next piece of magic avoids the "deleted header file" problem.
193 ## The problem is that when a header file which appears in a .P file
194 ## is deleted, the dependency causes make to die (because there is
195 ## typically no way to rebuild the header). We avoid this by adding
196 ## dummy dependencies for each header file. Too bad gcc doesn't do
197 ## this for us directly.
198 ## Some versions of gcc put a space before the ':'. On the theory
199 ## that the space means something, we add a space to the output as
200 ## well. hp depmode also adds that space, but also prefixes the VPATH
201 ## to the object. Take care to not repeat it in the output.
202 ## Some versions of the HPUX 10.20 sed can't process this invocation
203 ## correctly. Breaking it into two sed invocations is a workaround.
204 tr ' ' "$nl" < "$tmpdepfile" \
205 | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
206 | sed -e 's/$/ :/' >> "$depfile"
207 rm -f "$tmpdepfile"
210 gcc_compile ()
212 local arg="$@"
214 ## gcc 3 implements dependency tracking that does exactly what
215 ## we want. Yay! Note: for some reason libtool 1.4 doesn't like
216 ## it if -MD -MP comes after the -MF stuff. Hmm.
217 ## Unfortunately, FreeBSD c89 acceptance of flags depends upon
218 ## the command line argument order; so add the flags where they
219 ## appear in depend2.am. Note that the slowdown incurred here
220 ## affects only configure: in makefiles, %FASTDEP% shortcuts this.
221 for arg
223 case $arg in
224 -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
225 *) set fnord "$@" "$arg" ;;
226 esac
227 shift # fnord
228 shift # $arg
229 done
230 "$@"
231 stat=$?
232 if test $stat -ne 0; then
233 rm -f "$tmpdepfile"
234 exit $stat
236 mv "$tmpdepfile" "$depfile"
239 gcc_compile ()
241 depcomp $@
246 ######################
247 # section: public function
248 ######################
251 # fsyntax: init_toolchain_param
252 # fdesc: toolchain variable define.
254 init_toolchain_param ()
256 local vname=
257 local prog=
259 if [[ -n $CROSS_COMPILER ]]; then
260 CROSS="$CROSS_COMPILER"
261 elif [[ -z $CROSS ]]; then
262 [[ -n $TARGET ]] && CROSS="${TARGET}-"
263 [[ -n $SYSTEM ]] && CROSS+="${SYSTEM}-"
264 [[ -n $XXX ]] && CROSS+="${XXX}-"
265 else
269 TOOLCHAIN_PROG_LIST=''
270 while read vname; do
271 [[ -z $vname ]] && continue
272 prog="${CPLR_NAME^^}_${vname^^}"
273 if [[ -n ${!prog} ]]; then
274 eval "${vname}=\"${CROSS}${!prog}\""
275 else
276 eval "${vname}=\"${CROSS}${vname,,}\""
278 TOOLCHAIN_VAR_LIST+="${vname}$'\n'"
279 TOOLCHAIN_PROG_LIST+="${vname}=\"${!vname}\"$'\n'"
280 done <<< "${TOOLCHAIN_LIST}"
282 # default link program is 'ld'. it can be setted by 'gcc'
283 # in toolchain define.
284 [[ -z $LINK ]] && LINK="${LD}"
287 init_toolchain_param
290 toolchain_init ()
292 # get toolchain type, and load corresponding paramters.
298 # fsyntax: ASFLAGS_gen
299 # fdesc: paramter ASFLAGS generating.
300 # input:
301 # ASFLAGS_XXX, various kinds of variable with 'ASFLAGS_' pfx.
302 # output:
303 # ASFLAGS
305 ASFLAGS_gen ()
311 # fsyntax: CFLAGS_gen
312 # fdesc: paramter CFLAGS generating.
313 # input:
314 # CFLAGS_XXX, various kinds of variable with 'CFLAGS_' pfx.
315 # output:
316 # CFLAGS
318 CFLAGS_gen ()
324 # fsyntax: CPPFLAGS_gen
325 # fdesc: paramter CPPFLAGS generating.
326 # input:
327 # CPPFLAGS_XXX, various kinds of variable with 'CPPFLAGS_' pfx.
328 # output:
329 # CPPFLAGS
331 CPPFLAGS_gen ()
337 # fsyntax: LDFLAGS_gen
338 # fdesc: paramter LDFLAGS generating.
339 # input:
340 # LDFLAGS_XXX, various kinds of variable with 'LDFLAGS_' pfx.
341 # output:
342 # LDFLAGS
344 LDFLAGS_gen ()
350 # fsyntax: toolchain_chk
351 # fdesc: check toolchain if it can works in usual. save flags in
352 # build-pkg config file.
354 toolchain_chk ()
356 # TBD:
361 # fsyntax: dev_env_chk
362 # fdesc: check commands and build env.
364 dev_env_chk ()
366 # TBD:
371 # fsyntax: dep_lib_chk
372 # fdesc: check external lib file if it exist and can works.
373 # save checking resualt into build-pkg config file.
375 dep_lib_chk ()
377 # TBD:
382 # fsyntax: dep_syshdr_chk
383 # fdesc: check system .h file if it exist.
385 dep_syshdr_chk ()
387 # TBD:
391 #########################################
392 # Compile Function
393 #########################################
396 # fsyntax: asm2o <src-file> <output-file>
397 # fdesc: asm汇编程序.S文件编译成.o文件。
399 asm2o ()
401 local cmd=
402 local output=
403 local ret=
405 # attention -lncurses paramter must be put after .o file,
406 # or it report err that symbol not found.
407 cmd="${AS} ${ASFLAGS_OUT} ${ASFLAGS_EXT} ${ASFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE}"
409 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
411 # build operation
412 output="$( eval $cmd 2>&1; )"
413 ret=$?
415 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
416 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
418 if [[ $ret == 0 || -z "$output" ]]; then
419 echo -ne " === ${cmd}\n"
420 else
421 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
422 echo "$output"
423 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
426 return $ret
430 # fsyntax: c2o <src-file>
431 # fdesc: c语言程序.c文件编译成.o文件。
432 c2o ()
434 local cmd=
435 local output=
436 local ret=
437 local srcdir=
438 local dstdir=
440 info "c2o ($@)\n"
442 SRC_FILE[0]="$1"
443 src2dst_filename
445 srcdir="$(dirname ${SRC_FILE[0]})"
446 dstdir="$(dirname ${DST_FILE[0]})"
447 mkdir -p $srcdir $dstdir
449 echo "CFLAGS_EVL=$CFLAGS_EVL"
450 echo "CFLAGS=$CFLAGS"
452 CCFLAGS_DEPHDR=""
453 CCFLAGS_CALLGRAPH=""
454 if [[ -n ${DST_FILE[1]} ]]; then
455 eval "CCFLAGS_DEPHDR=\"$CCFLAGS_DEPHDR_EVL\"" >> ${OUTPUT_DIR}/build-dbgout.log
457 if [[ -n ${DST_FILE[2]} ]]; then
458 eval "CCFLAGS_CALLGRAPH=\"$CCFLAGS_CALLGRAPH_EVL\"" >> ${OUTPUT_DIR}/build-dbgout.log
461 echo CCFLAGS_DEPHDR="$CCFLAGS_DEPHDR" >> ${OUTPUT_DIR}/build-dbgout.log
462 echo CCFLAGS_CALLGRAPH="$CCFLAGS_CALLGRAPH" >> ${OUTPUT_DIR}/build-dbgout.log
464 # ${SRC_DEP_OPT:="$CCFLAGS_DEPHDR"} ==> $CCFLAGS_DEPHDR
465 cmd="${CC} ${CFLAGS_OUT} ${CFLAGS_EXT} ${CFLAGS} ${CCFLAGS_DEPHDR} ${CCFLAGS_CALLGRAPH} -c ${SRC_FILE[0]} -o ${DST_FILE[0]}"
467 output="$( eval $cmd 2>&1; )"
468 ret=$?
470 echo -ne "${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
471 echo -ne "${cmd}\n" 2>&1 >> ${OUTPUT_DIR}/build.log
473 if [[ $ret == 0 || -z "$output" ]]; then
474 echo -ne "${cmd}\n"
475 echo "$output"
476 else
477 echo -ne "${CHIGHL}${cmd}${CNORMAL}\n"
478 echo "$output"
479 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
482 [[ $ret != 0 ]] && ret=2
483 return $ret
487 # fsyntax: cxx2o
488 # fdesc: .cc文件编译成.o文件。
489 cxx2o ()
491 local cmd=
492 local output=
493 local ret=
495 CCFLAGS_DEPHDR=""
496 CCFLAGS_CALLGRAPH=""
497 if [[ -n ${DST_FILE[1]} ]]; then
498 eval "CCFLAGS_DEPHDR=\"$CCFLAGS_DEPHDR_EVL\"" >> ${OUTPUT_DIR}/build-dbgout.log
500 if [[ -n ${DST_FILE[2]} ]]; then
501 eval "CCFLAGS_CALLGRAPH=\"$CCFLAGS_CALLGRAPH_EVL\"" >> ${OUTPUT_DIR}/build-dbgout.log
504 echo CCFLAGS_DEPHDR="$CCFLAGS_DEPHDR" >> ${OUTPUT_DIR}/build-dbgout.log
505 echo CCFLAGS_CALLGRAPH="$CCFLAGS_CALLGRAPH" >> ${OUTPUT_DIR}/build-dbgout.log
507 # ${SRC_DEP_OPT:="$CCFLAGS_DEPHDR"} ==> $CCFLAGS_DEPHDR
508 cmd="${CXX} ${CXXFLAGS_OUT} ${CXXFLAGS_EXT} ${CXXFLAGS} ${CCFLAGS_DEPHDR} ${CCFLAGS_CALLGRAPH} -c ${SRC_FILE[0]} -o ${DST_FILE[0]}"
510 output="$( eval $cmd 2>&1; )"
511 ret=$?
513 echo -ne "${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
514 echo -ne "${cmd}\n" 2>&1 >> ${OUTPUT_DIR}/build.log
516 if [[ $ret == 0 || -z "$output" ]]; then
517 echo -ne "${cmd}\n"
518 echo "$output"
519 else
520 echo -ne "${CHIGHL}${cmd}${CNORMAL}\n"
521 echo "$output"
522 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
525 return $ret
529 # fsyntax: cpp2o
530 # fdesc: cpp程序.cpp文件编译成.o文件。
532 cpp2o ()
534 local cmd=
535 local output=
536 local ret=
538 CCFLAGS_DEPHDR=""
539 CCFLAGS_CALLGRAPH=""
540 if [[ -n ${DST_FILE[1]} ]]; then
541 eval "CCFLAGS_DEPHDR=\"$CCFLAGS_DEPHDR_EVL\"" >> ${OUTPUT_DIR}/build-dbgout.log
543 if [[ -n ${DST_FILE[2]} ]]; then
544 eval "CCFLAGS_CALLGRAPH=\"$CCFLAGS_CALLGRAPH_EVL\"" >> ${OUTPUT_DIR}/build-dbgout.log
547 echo CCFLAGS_DEPHDR="$CCFLAGS_DEPHDR" >> ${OUTPUT_DIR}/build-dbgout.log
548 echo CCFLAGS_CALLGRAPH="$CCFLAGS_CALLGRAPH" >> ${OUTPUT_DIR}/build-dbgout.log
550 # attention -lncurses paramter must be put after .o file,
551 # or it report err that symbol not found.
552 cmd="${CPP} ${CPPFLAGS_OUT} ${CPPFLAGS_EXT} ${CPPFLAGS} ${CCFLAGS_DEPHDR} ${CCFLAGS_CALLGRAPH} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}"
554 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
556 # build operation
557 output="$( eval $cmd 2>&1; )"
558 ret=$?
560 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
561 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
563 if [[ $ret == 0 || -z "$output" ]]; then
564 echo -ne "${cmd}\n"
565 echo "$output"
566 else
567 echo -ne "${CHIGHL}${cmd}${CNORMAL}\n"
568 echo "$output"
569 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
572 return $ret
575 EXE_LINK="tpchk o2exe"
576 DLL_LINK="tpchk o2dll"
577 DRV_LINK="tpchk o2drv"
578 LIB_LINK="tpchk o2lib"
579 LA_LINK="tpchk o2la"
580 O_LINK="tpchk o2o"
581 LO_LINK="tpchk o2lo"
585 # fsyntax: asm2exe
586 # fdesc: .asm文件编译成exe文件。
587 asm2exe ()
589 local cmd=
590 local output=
591 local ret=
593 # attention -lncurses paramter must be put after .o file,
594 # or it report err that symbol not found.
595 cmd="${CC} ${ASFLAGS_OUT} ${ASFLAGS_EXT} ${CFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}"
597 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
599 # build operation
600 output="$( eval $cmd 2>&1; )"
601 ret=$?
603 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
604 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
606 if [[ $ret == 0 || -z "$output" ]]; then
607 echo -ne " === ${cmd}\n"
608 else
609 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
610 echo "$output"
611 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
614 return $ret
618 # fsyntax: c2exe
619 # fdesc: c语言程序.c文件编译成.o文件。
620 c2exe ()
622 local cmd=
623 local output=
624 local ret=
626 # attention -lncurses paramter must be put after .o file,
627 # or it report err that symbol not found.
628 cmd="${CC} ${CFLAGS_OUT} ${CFLAGS_EXT} ${CFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}"
630 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
632 # build operation
633 output="$( eval $cmd 2>&1; )"
634 ret=$?
636 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
637 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
639 if [[ $ret == 0 || -z "$output" ]]; then
640 echo -ne " === ${cmd}\n"
641 else
642 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
643 echo "$output"
644 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
647 return $ret
651 # fsyntax: cxx2exe
652 # fdesc: cpp程序.cpp文件编译成.o文件。
654 cxx2exe ()
656 local cmd=
657 local output=
658 local ret=
660 # attention -lncurses paramter must be put after .o file,
661 # or it report err that symbol not found.
662 cmd="${CXX} ${CXXFLAGS_OUT} ${CXXFLAGS_EXT} ${CPPFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}"
664 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
666 # build operation
667 output="$( eval $cmd 2>&1; )"
668 ret=$?
670 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
671 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
673 if [[ $ret == 0 || -z "$output" ]]; then
674 echo -ne " === ${cmd}\n"
675 else
676 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
677 echo "$output"
678 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
681 return $ret
685 # fsyntax: cpp2exe
686 # fdesc: cpp程序.cpp文件编译成.o文件。
688 cpp2exe ()
690 local cmd=
691 local output=
692 local ret=
694 # attention -lncurses paramter must be put after .o file,
695 # or it report err that symbol not found.
696 cmd="${CPP} ${CPPFLAGS_OUT} ${CPPFLAGS_EXT} ${CPPFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}"
698 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
700 # build operation
701 output="$( eval $cmd 2>&1; )"
702 ret=$?
704 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
705 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
707 if [[ $ret == 0 || -z "$output" ]]; then
708 echo -ne " === ${cmd}\n"
709 else
710 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
711 echo "$output"
712 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
715 return $ret
719 # fsyntax: c2h
720 # fdesc: c语言程序.c文件,输出/同步更新到模块对应的.h文件。
722 c2h ()
728 # fsyntax: cpp2h
729 # fdesc: cpp程序.cpp文件,输出/同步更新到模块对应的.h文件。
731 cpp2h ()
737 # fsyntax: srcdep
738 # fdesc: 源文件编译需要的.h文件的dep文件的创建,.h文件更新时,.dep文件需要更新,
739 # 对应的src文件重新编译。
741 srcdep ()
743 local SRC_FILE="$1"
744 local DST_FILE="$2"
746 ${CC} -MM -MT $SRC_FILE -MF ${DST_FILE//.o/.d} $DST_FILE
749 #########################################
750 # link function
751 #########################################
754 # fsyntax: o2o
755 # fdesc: .o文件链接成.o文件。
757 o2o ()
759 local cmd=
760 local output=
761 local ret=
763 # ${CC} ${LDFLAGS} ${LIB_OBJECT} ${LIBS}
764 cmd="${LINK} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]} ${LDFLAGS}"
766 # build operation
767 output="$( eval $cmd 2>&1; )"
768 ret=$?
770 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
771 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
773 if [[ $ret == 0 || -z "$output" ]]; then
774 echo -ne " === ${cmd}\n"
775 else
776 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
777 echo "$output"
778 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
781 return $ret
785 # fsyntax: src2dst_filename
786 # fdesc: compile each src file.
788 link_filename_fix ()
790 local ext=
791 local dst=
793 ext="${LANG_EXT_NAME[${lang,,}]}"
794 #"${SRC_FILE[0]##*.}"
796 # obj="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${obj//\.$ext/\.o}"
798 # DST_FILE[0]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${DST_FILE[0]}"
800 for ((i=0; i<${#SRC_FILE[@]}; i++)); do
801 SRC_FILE[$i]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${SRC_FILE[$i]}"
802 done
806 # fsyntax: o2lib
807 # fdesc: .o文件链接成.a文件。
809 o2lib ()
811 local cmd=
812 local output=
813 local ret=
815 link_filename_fix
817 # attention -lncurses paramter must be put after .o file,
818 # or it report err that symbol not found.
819 cmd="${AR} ${ARFLAGS} ${DST_FILE[0]} $(echo ${SRC_FILE[@]})"
821 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
823 # build operation
824 output="$( eval $cmd 2>&1; )"
825 ret=$?
827 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
828 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
830 if [[ $ret == 0 || -z "$output" ]]; then
831 echo -ne " === ${cmd}\n"
832 else
833 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
834 echo "$output"
835 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
838 ranlib ${DST_FILE[0]}
840 return $ret
844 # fsyntax: o2la
845 # fdesc: .o文件链接成.la文件。
847 o2la ()
853 # fsyntax: o2dlib
854 # fdesc: .o文件链接成.so文件。
856 o2dlib ()
858 local cmd=
859 local output=
860 local ret=
862 # XXX: if some symbol display 'undefined reference to ', maybe the lib param -lxxx
863 # is before then the lib -lyyy which is referenced by some symbol.
865 # ${CC} ${LDFLAGS} ${LIB_OBJECT} ${LIBS}
866 cmd="${LINK} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]} ${LDFLAGS} ${LDFLAGS_SHARED}"
868 # build operation
869 output="$( eval $cmd 2>&1; )"
870 ret=$?
872 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
873 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
875 if [[ $ret == 0 || -z "$output" ]]; then
876 echo -ne " === ${cmd}\n"
877 else
878 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
879 echo "$output"
880 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
883 return $ret
887 # fsyntax: o2exe
888 # fdesc: .o文件链接成elf可执行文件。
890 o2exe ()
892 local cmd=
893 local output=
894 local ret=
896 link_filename_fix
898 # cmd="${SRC_FILE[@]}"
900 # attention -lncurses paramter must be put after .o file,
901 # or it report err that symbol not found.
902 cmd="${LINK} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]} ${LDFLAGS} ${LIBS}"
904 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
906 # return 0
908 # build operation
909 output="$( eval $cmd 2>&1; )"
910 ret=$?
912 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
913 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
915 if [[ $ret == 0 || -z "$output" ]]; then
916 echo -ne " === ${cmd}\n"
917 else
918 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
919 echo "$output"
920 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
923 return $ret
927 # fsyntax: o2drv
928 # fdesc: .o文件链接成elf格式linux的drv文件。
930 o2drv ()
932 local cmd=
933 local output=
934 local ret=
936 # attention -lncurses paramter must be put after .o file,
937 # or it report err that symbol not found.
938 cmd="${LINK} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]} ${DRVLDFLAGS}"
940 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
942 # build operation
943 output="$( eval $cmd 2>&1; )"
944 ret=$?
946 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
947 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
949 if [[ $ret == 0 || -z "$output" ]]; then
950 echo -ne " === ${cmd}\n"
951 else
952 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
953 echo "$output"
954 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
957 return $ret
960 #########################################
961 # build postage processing & info.
962 # size of .text/.data/.rodata/.bss.
963 # internal symbol of an executable file.
964 # export symbol of an executable file.
967 # nm -D <file>, dynamic symbol. U, imported; T, exported.
968 # nm -g <file>, global symbol, all symbol.
970 # objdump -t <file> | grep -e "\.text", native code symbol.
971 # objdump -t <file> | grep -e "\.data", initialized var symbol.
972 # objdump -t <file> | grep -e "\.rodata", read only var symbol.
973 # objdump -t <file> | grep -e "\.bss", uninitialized var symbol.
975 # size <file>, it display size info in .text/.data(.rodata)/.bss
976 #########################################
979 # fsyntax: progstrip
980 # fdesc: delete debug symbol info .etc .
982 progstrip ()
984 local cmd=
985 local output=
986 local ret=
988 # attention -lncurses paramter must be put after .o file,
989 # or it report err that symbol not found.
990 cmd="${STRIP} $(echo ${DST_FILE[@]})"
992 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
994 # build operation
995 output="$( eval $cmd 2>&1; )"
996 ret=$?
998 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
999 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
1001 if [[ $ret == 0 || -z "$output" ]]; then
1002 echo -ne " === ${cmd}\n"
1003 else
1004 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
1005 echo "$output"
1006 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
1009 return $ret
1013 # fsyntax: prog_sizeinfo
1014 # fdesc: size of .text/.data/.rodata/.bss.
1016 prog_sizeinfo ()
1018 local cmd=
1019 local output=
1020 local ret=
1022 echo "prog_sizeinfo ($@)"
1024 # attention -lncurses paramter must be put after .o file,
1025 # or it report err that symbol not found.
1026 cmd="${SIZE} $(echo ${SRC_FILE[@]})"
1028 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
1030 # build operation
1031 output="$( eval $cmd 2>&1; )"
1032 ret=$?
1034 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
1035 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
1037 if [[ $ret == 0 || -z "$output" ]]; then
1038 echo -ne " === ${cmd}\n"
1039 else
1040 echo -ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
1041 echo "$output"
1042 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
1045 return $ret
1048 # objdump -t <file> | grep -e "\.text", native code symbol.
1049 # objdump -t <file> | grep -e "\.data", initialized var symbol.
1050 # objdump -t <file> | grep -e "\.rodata", read only var symbol.
1051 # objdump -t <file> | grep -e "\.bss", uninitialized var symbol.
1055 # fsyntax: prog_symboals
1056 # fdesc: output .text/.data/.rodata/.bss symbols in executables.
1058 prog_symboals ()
1060 local file=
1062 while read file; do
1063 echo "[$file]"
1064 objdump -t $file | 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///g; s/\.data/var-i/g; s/\.bss/var/g; s/\.rodata/var-e/g;"
1065 done <<< "${SRC_FILE[@]}"
1068 SYMB_FILTER_SYS='y'
1071 # fsyntax: prog_inner_symbs
1072 # fdesc: output internal symbols in executables.
1074 prog_inner_symbs ()
1076 local file=
1077 local param=
1079 [[ $SYMB_FILTER_SYS == 'y' ]] && param="-v \"00000000\""
1081 while read file; do
1082 echo "[$file]"
1083 objdump -t $file | grep -o -e "\.text.*"| grep -v $'[ |\t]'"\..*" | sort | sed -e "s/\.text/func-i/g;"
1084 done <<< "${SRC_FILE[@]}"
1088 # fsyntax: prog_ext_symbs
1089 # fdesc: output external symbols in executables.
1091 prog_ext_symbs ()
1093 local file=
1095 while read file; do
1096 echo "[$file]"
1097 objdump -t $file | grep -o -e "\*UND\*.*"| grep -v $'[ |\t]'"\..*" | grep -v \"00000000\" | sort | sed -e "s/\*UND\*/func-e/g; s///g;"
1098 done <<< "${SRC_FILE[@]}"
1102 # fsyntax: prog_func_symbs
1103 # fdesc: output function symbols in executables.
1105 prog_func_symbs ()
1107 local file=
1109 while read file; do
1110 echo "[$file]"
1111 objdump -t $file | grep -o -e "\*UND\*.*" -e "\.text.*" | grep -v $'[ |\t]'"\..*" | sort | sed -e "s/\.text/func-i/g; s/\*UND\*/func-e/g; s///g;"
1112 done <<< "${SRC_FILE[@]}"
1116 # fsyntax: prog_func_symbs
1117 # fdesc: output function symbols in executables.
1119 prog_var_symbs ()
1121 local file=
1123 while read file; do
1124 echo "[$file]"
1125 objdump -t $file | 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; s///g;"
1126 done <<< "${SRC_FILE[@]}"
1130 #########################################
1131 # bin/hex output and transform.
1132 #########################################
1136 # fsyntax: exe2hex
1137 # fdesc: bin二进制文件转换成hex字符串。
1139 exe2hex ()
1145 # fsyntax: exe2bin
1146 # fdesc: elf文件读取code/data的section,保存成bin文件。
1147 # 通常用于非操作系统环境下运行的程序。
1149 exe2bin ()
1151 objcopy -t $file | 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; s///g;"
1155 # fsyntax: bin2hex
1156 # fdesc: bin二进制文件转换成hex字符串。
1158 bin2hex ()
1164 # fsyntax: hex2bin
1165 # fdesc: hex字符串转换成bin二进制数据文件。
1167 hex2bin ()
1173 # fsyntax: fbin2fhex
1174 # fdesc: bin二进制文件转换成hex文件。
1176 fbin2fhex ()
1182 # fsyntax: fhex2fbin
1183 # fdesc: hex文件转换成bin二进制数据文件。
1185 fhex2fbin ()
1192 ######################
1193 # section: file tail
1194 ######################
1196 return 0
1202 # fsyntax: bin2hex
1203 # fdesc: bin二进制文件转换成hex字符串。
1205 objlist ()
1212 INPUT[0]=""
1213 OUTPUT[0]=""
1215 CMPL_FUNC ()
1217 local srcdir="$(dirname ${SRC_FILE[0]})"
1218 local dstdir="$(dirname ${DST_FILE[0]})"
1219 local src="${SRC_FILE[0]}"
1220 local dst="${DST_FILE[0]}"
1221 local dep="${DST_FILE[1]}"
1222 local dephdr=
1223 local file=
1224 local flag=
1226 mkdir -p $srcdir $dstdir
1228 echo srcdir=$srcdir >> ${OUTPUT_DIR}/build-dbgout.log
1230 echo src=$src >> ${OUTPUT_DIR}/build-dbgout.log
1231 echo dst=$dst >> ${OUTPUT_DIR}/build-dbgout.log
1232 echo dep=$dep >> ${OUTPUT_DIR}/build-dbgout.log
1234 if [[ ! -e "${DST_FILE[0]}" ]]; then
1235 flag=compile
1238 if [[ -e "${DST_FILE[1]}" ]]; then
1239 dephdr=( $(cat ${DST_FILE[1]} | grep -e ":[[:blank:]]*$") )
1240 echo dephdr="${dephdr[@]}\n" >> ${OUTPUT_DIR}/build-dbgout.log
1241 else
1242 flag=compile
1245 # src file time stamp chk.
1246 if [[ $src -nt $dst || $src -nt $dep ]]; then
1247 flag=compile
1248 echo "$src is newer then $dst." >> ${OUTPUT_DIR}/build-dbgout.log
1251 # hdr file time stamp chk.
1252 for file in ${dephdr[@]}; do
1253 # [[ ${file:0:1} != '/' ]] && file="$srcdir/$file"
1254 file=${file:0:-1}
1255 echo file="${file}" >> ${OUTPUT_DIR}/build-dbgout.log
1256 if [[ $file -nt $dst ]]; then
1257 flag=compile
1258 echo "$file is newer then $dst." >> ${OUTPUT_DIR}/build-dbgout.log
1259 break;
1261 done
1263 echo flag=$flag >> ${OUTPUT_DIR}/build-dbgout.log
1265 if [[ $flag != compile ]]; then
1266 return 0
1269 echo [CC] ${SRC_FILE[0]} ${DST_FILE[0]} >> ${OUTPUT_DIR}/build-compact-info.log
1272 return $?