2 ############################################################
3 # source: toolchain.shlib
4 # author: devenkong(18151155@qq.com)
6 ############################################################
9 ############################################################
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.
30 # @ different cpu arch optimzation opt.
32 # @ compile hdr file dep list.
35 # @ prev & post invoke
45 ######################
46 # section: common comment info
47 ######################
49 ######################
50 # section: variable define
51 ######################
53 # just use GNU, or append gcc version
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
=''
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_DEPHDR_EVL=' -MM -MT ${DST_FILE[0]} -MF ${DST_FILE[1]} '
101 #CCFLAGS_DEPHDR_EVL=' -MM -MT ${DST_FILE} -MF ${SRC_FILE//.c[p]?[p]?/.dep} '
102 #CCFLAGS_DEPHDR_EVL=' -MT "$object" -MD -MP -MF "$tmpdepfile"'
104 # it uses this paramter in depcomp
105 # -MT "$object" -MD -MP -MF "$tmpdepfile"
108 C2O_CMD_EVL
='${CC} ${CFLAGS_OUT} ${CFLAGS_EXT} ${CFLAGS} ${CCFLAGS_DEPHDR} ${CCFLAGS_CALLGRAPH} -c ${SRC_FILE[0]} -o ${DST_FILE[0]}'
109 CXX2O_CMD_EVL
='${CXX} ${CXXFLAGS_OUT} ${CXXFLAGS_EXT} ${CXXFLAGS} ${CCFLAGS_DEPHDR} ${CCFLAGS_CALLGRAPH} -c ${SRC_FILE[0]} -o ${DST_FILE[0]}'
110 CPP2O_CMD_EVL
='${CPP} ${CPPFLAGS_OUT} ${CPPFLAGS_EXT} ${CPPFLAGS} ${CCFLAGS_DEPHDR} ${CCFLAGS_CALLGRAPH} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}'
112 O2O_CMD_EVL
='${LINK} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]} ${LDFLAGS}'
113 O2LIB_CMD_EVL
='${AR} ${ARFLAGS} ${DST_FILE[0]} $(echo ${SRC_FILE[@]})'
114 O2DLL_CMD_EVL
='${LINK} $(echo ${SRC_FILE[@]}) $(echo ${STATIC_LIB_LIST[@]}) -o ${DST_FILE[0]} ${LDFLAGS} ${LDFLAGS_SHARED}'
115 O2EXE_CMD_EVL
='${LINK} $(echo ${SRC_FILE[@]}) $(echo ${STATIC_LIB_LIST[@]}) -o ${DST_FILE[0]} ${LDFLAGS} ${LIBS}'
116 O2DRV_CMD_EVL
='${LINK} $(echo ${SRC_FILE[@]}) $(echo ${STATIC_LIB_LIST[@]}) -o ${DST_FILE[0]} ${DRVLDFLAGS}'
118 ASM2EXE_CMD_EVL
='${CC} ${ASFLAGS_OUT} ${ASFLAGS_EXT} ${CFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}'
119 C2EXE_CMD_EVL
='${CC} ${CFLAGS_OUT} ${CFLAGS_EXT} ${CFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}'
120 CXX2EXE_CMD_EVL
='${CXX} ${CXXFLAGS_OUT} ${CXXFLAGS_EXT} ${CPPFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}'
121 CPP2EXE_CMD_EVL
='${CPP} ${CPPFLAGS_OUT} ${CPPFLAGS_EXT} ${CPPFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}'
125 ######################
126 # section: private function
127 ######################
136 # fsyntax: src2dst_filename
137 # fdesc: compile each src file.
143 ext
="${SRC_FILE[0]##*.}"
145 obj
="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${obj//\.$ext/\.o}"
147 DST_FILE
[0]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${SRC_FILE[0]//\.$ext/\.o}"
148 DST_FILE
[1]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${SRC_FILE[0]//\.$ext/\.dep}"
149 SRC_FILE
[0]="${SRCPKG_TOPDIR}/${SRC_FILE[0]}"
154 ######################
155 # section: public function
156 ######################
159 # fsyntax: init_toolchain_param
160 # fdesc: toolchain variable define.
162 init_toolchain_param
()
167 if test -n "$CROSS_COMPILER" ; then
168 CROSS
="$CROSS_COMPILER"
169 elif test -z "$CROSS" ; then
170 [[ -n $TARGET ]] && CROSS
="${TARGET}-"
171 [[ -n $SYSTEM ]] && CROSS
+="${SYSTEM}-"
172 [[ -n $XXX ]] && CROSS
+="${XXX}-"
177 TOOLCHAIN_PROG_LIST
=''
179 [[ -z $vname ]] && continue
180 prog
="${CPLR_NAME^^}_${vname^^}"
181 if test -n "${!prog}" ; then
182 eval "${vname}=\"${CROSS}${!prog}\""
184 eval "${vname}=\"${CROSS}${vname,,}\""
186 TOOLCHAIN_VAR_LIST
+="${vname}$'\n'"
187 TOOLCHAIN_PROG_LIST
+="${vname}=\"${!vname}\"$'\n'"
188 done <<< "${TOOLCHAIN_LIST}"
190 # default link program is 'ld'. it can be setted by 'gcc'
191 # in toolchain define.
192 [[ -z $LINK ]] && LINK
="${LD}"
200 # get toolchain type, and load corresponding paramters.
204 #########################################
206 #########################################
214 # attention -lncurses paramter must be put after .o file,
215 # or it report err that symbol not found.
216 # cmd="${CC} ${ASFLAGS_OUT} ${ASFLAGS_EXT} ${CFLAGS} ${LDFLAGS} $(echo ${SRC_FILE[@]}) -o ${DST_FILE[0]}"
218 toolchain_dbgout
-ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
221 output
="$( eval $cmd 2>&1; )"
224 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
225 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
227 if test $ret == 0 ||
test -z "$output" ; then
228 toolchain_dbgout
-ne " === ${cmd}\n"
230 info
-ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
232 toolchain_dbgout
"$output" >> ${OUTPUT_DIR}/build-dbgout.log
235 if test $ret != 0 ; then
243 # fsyntax: asm2o <src-file> <output-file>
244 # fdesc: asm汇编程序.S文件编译成.o文件。
250 eval cmd
=\"$ASM2O_CMD_EVL\"
256 # fsyntax: c2o <src-file>
257 # fdesc: c语言程序.c文件编译成.o文件。
267 srcdir
="$(dirname ${SRC_FILE[0]})"
268 dstdir
="$(dirname ${DST_FILE[0]})"
269 mkdir
-p $srcdir $dstdir
273 if test -n "${DST_FILE[1]}" ; then
274 eval "CCFLAGS_DEPHDR=\"$CCFLAGS_DEPHDR_EVL\""
276 if test -n "${DST_FILE[2]}" ; then
277 eval "CCFLAGS_CALLGRAPH=\"$CCFLAGS_CALLGRAPH_EVL\""
280 eval cmd
=\"$C2O_CMD_EVL\"
287 # fdesc: .cc文件编译成.o文件。
296 if test -n "${DST_FILE[1]}" ; then
297 eval "CCFLAGS_DEPHDR=\"$CCFLAGS_DEPHDR_EVL\""
299 if test -n "${DST_FILE[2]}" ; then
300 eval "CCFLAGS_CALLGRAPH=\"$CCFLAGS_CALLGRAPH_EVL\""
303 eval cmd
=\"$CXX2O_CMD_EVL\"
310 # fdesc: cpp程序.cpp文件编译成.o文件。
320 if test -n "${DST_FILE[1]}" ; then
321 eval "CCFLAGS_DEPHDR=\"$CCFLAGS_DEPHDR_EVL\""
323 if test -n "${DST_FILE[2]}" ; then
324 eval "CCFLAGS_CALLGRAPH=\"$CCFLAGS_CALLGRAPH_EVL\""
327 eval cmd
=\"$CPP2O_CMD_EVL\"
332 EXE_LINK
="tpchk o2exe"
333 DLL_LINK
="tpchk o2dll"
334 DRV_LINK
="tpchk o2drv"
335 LIB_LINK
="tpchk o2lib"
343 # fdesc: .asm文件编译成exe文件。
348 eval cmd
=\"$ASM2EXE_CMD_EVL\"
355 # fdesc: c语言程序.c文件编译成.o文件。
360 eval cmd
=\"$C2EXE_CMD_EVL\"
367 # fdesc: cpp程序.cpp文件编译成.o文件。
373 eval cmd
=\"$CXX2EXE_CMD_EVL\"
380 # fdesc: cpp程序.cpp文件编译成.o文件。
386 eval cmd
=\"$CPP2EXE_CMD_EVL\"
392 #########################################
394 #########################################
398 # fdesc: .o文件链接成.o文件。
404 eval cmd
=\"$O2O_CMD_EVL\"
410 # fsyntax: link_filename_fix
411 # fdesc: compile each src file.
418 # eval "ext=\"\${LANG_EXT_NAME[${lang,,}]}\""
419 #"${SRC_FILE[0]##*.}"
421 # obj="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${obj//\.$ext/\.o}"
423 # DST_FILE[0]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${DST_FILE[0]}"
425 for ((i
=0; i
<${#SRC_FILE[@]}; i
++)); do
426 SRC_FILE
[$i]="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${SRC_FILE[$i]}"
432 # fdesc: .o文件链接成.a文件。
442 eval cmd
=\"$O2LIB_CMD_EVL\"
444 [[ $?
!= 0 ]] && return $?
446 ranlib
${DST_FILE[0]}
452 # fdesc: .o文件链接成.la文件。
457 # if test $ret != 0 ; then
466 # fdesc: .o文件链接成.so文件。
474 eval cmd
=\"$O2DLL_CMD_EVL\"
482 # fdesc: .o文件链接成.a文件。
492 DST_FILE
="${DST_FILE%\.*}.a"
494 eval cmd
=\"$O2LIB_CMD_EVL\"
496 [[ $?
!= 0 ]] && return $?
498 ranlib
${DST_FILE[0]}
499 [[ $?
!= 0 ]] && return $?
501 DST_FILE
="${DST_FILE%\.*}.so"
502 eval cmd
=\"$O2DLL_CMD_EVL\"
509 # fdesc: .o文件链接成elf可执行文件。
517 eval cmd
=\"$O2EXE_CMD_EVL\"
524 # fdesc: .o文件链接成elf格式linux的drv文件。
530 eval cmd
=\"$O2DRV_CMD_EVL\"
535 #########################################
536 # build postage processing & info.
537 # size of .text/.data/.rodata/.bss.
538 # internal symbol of an executable file.
539 # export symbol of an executable file.
542 # nm -D <file>, dynamic symbol. U, imported; T, exported.
543 # nm -g <file>, global symbol, all symbol.
545 # objdump -t <file> | grep -e "\.text", native code symbol.
546 # objdump -t <file> | grep -e "\.data", initialized var symbol.
547 # objdump -t <file> | grep -e "\.rodata", read only var symbol.
548 # objdump -t <file> | grep -e "\.bss", uninitialized var symbol.
550 # size <file>, it display size info in .text/.data(.rodata)/.bss
551 #########################################
555 # fdesc: delete debug symbol info .etc .
563 # attention -lncurses paramter must be put after .o file,
564 # or it report err that symbol not found.
565 cmd
="${STRIP} $(echo ${DST_FILE[@]})"
567 toolchain_dbgout
-ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
570 output
="$( eval $cmd 2>&1; )"
573 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
574 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
576 if test $ret == 0 ||
test -z "$output" ; then
577 toolchain_dbgout
-ne " === ${cmd}\n"
579 toolchain_dbgout
-ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
580 toolchain_dbgout
"$output"
581 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
584 if test $ret != 0 ; then
592 # fsyntax: prog_sizeinfo
593 # fdesc: size of .text/.data/.rodata/.bss.
603 toolchain_dbgout
"prog_sizeinfo ($@)"
605 for file in ${SRC_FILE[@]}; do
606 if test -f "${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${file}" ; then
607 filelist
+="${OUTPUT_DIR}/${DEST_CFG_DIR_NAME}/${file} "
610 filelist
+="${DST_FILE}"
612 # attention -lncurses paramter must be put after .o file,
613 # or it report err that symbol not found.
614 cmd
="${SIZE} ${filelist}"
616 toolchain_dbgout
-ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
619 output
="$( eval $cmd 2>&1; )"
622 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build-dbgout.log
623 echo -ne " === ${cmd}\n" >> ${OUTPUT_DIR}/build.log
625 if test $ret == 0 ||
test -z "$output" ; then
626 toolchain_dbgout
-ne " === ${cmd}\n"
629 toolchain_dbgout
-ne "${CHIGHL} === ${cmd}${CNORMAL}\n"
631 echo "$output" >> ${OUTPUT_DIR}/build-dbgout.log
634 if test $ret != 0 ; then
641 # objdump -t <file> | grep -e "\.text", native code symbol.
642 # objdump -t <file> | grep -e "\.data", initialized var symbol.
643 # objdump -t <file> | grep -e "\.rodata", read only var symbol.
644 # objdump -t <file> | grep -e "\.bss", uninitialized var symbol.
648 # fsyntax: prog_symboals
649 # fdesc: output .text/.data/.rodata/.bss symbols in executables.
657 toolchain_dbgout
"[$file]"
658 { 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///g; s/\.data/var-i/g; s/\.bss/var/g; s/\.rodata/var-e/g;"
659 [[ $ret != 0 ]] && break;
660 done <<< "${SRC_FILE[@]}"
662 if test $ret != 0 ; then
672 # fsyntax: prog_inner_symbs
673 # fdesc: output internal symbols in executables.
681 [[ $SYMB_FILTER_SYS == 'y' ]] && param
="-v \"00000000\""
684 toolchain_dbgout
"[$file]"
685 { objdump
-t $file; ret
=$?
; } |
grep -o -e "\.text.*"|
grep -v $
'[ |\t]'"\..*" |
sort |
sed -e "s/\.text/func-i/g;"
686 done <<< "${SRC_FILE[@]}"
688 if test $ret != 0 ; then
696 # fsyntax: prog_ext_symbs
697 # fdesc: output external symbols in executables.
705 toolchain_dbgout
"[$file]"
706 { objdump
-t $file; ret
=$?
; } |
grep -o -e "\*UND\*.*"|
grep -v $
'[ |\t]'"\..*" |
grep -v \"00000000\" |
sort |
sed -e "s/\*UND\*/func-e/g; s///g;"
707 done <<< "${SRC_FILE[@]}"
709 if test $ret != 0 ; then
717 # fsyntax: prog_func_symbs
718 # fdesc: output function symbols in executables.
726 toolchain_dbgout
"[$file]"
727 { 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; s///g;"
728 done <<< "${SRC_FILE[@]}"
730 if test $ret != 0 ; then
738 # fsyntax: prog_func_symbs
739 # fdesc: output function symbols in executables.
747 toolchain_dbgout
"[$file]"
748 { 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; s///g;"
749 done <<< "${SRC_FILE[@]}"
751 if test $ret != 0 ; then
759 #########################################
760 # bin/hex output and transform.
761 #########################################
766 # fdesc: bin二进制文件转换成hex字符串。
775 # fdesc: elf文件读取code/data的section,保存成bin文件。
782 { 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; s///g;"
784 if test $ret != 0 ; then
793 # fdesc: bin二进制文件转换成hex字符串。
802 # fdesc: hex字符串转换成bin二进制数据文件。
811 # fdesc: bin二进制文件转换成hex文件。
820 # fdesc: hex文件转换成bin二进制数据文件。
829 ######################
831 ######################
837 # fsyntax: ASFLAGS_gen
838 # fdesc: paramter ASFLAGS generating.
840 # ASFLAGS_XXX, various kinds of variable with 'ASFLAGS_' pfx.
850 # fsyntax: CFLAGS_gen
851 # fdesc: paramter CFLAGS generating.
853 # CFLAGS_XXX, various kinds of variable with 'CFLAGS_' pfx.
863 # fsyntax: CPPFLAGS_gen
864 # fdesc: paramter CPPFLAGS generating.
866 # CPPFLAGS_XXX, various kinds of variable with 'CPPFLAGS_' pfx.
876 # fsyntax: LDFLAGS_gen
877 # fdesc: paramter LDFLAGS generating.
879 # LDFLAGS_XXX, various kinds of variable with 'LDFLAGS_' pfx.
889 # fsyntax: toolchain_chk
890 # fdesc: check toolchain if it can works in usual. save flags in
891 # build-pkg config file.
900 # fsyntax: dev_env_chk
901 # fdesc: check commands and build env.
910 # fsyntax: dep_lib_chk
911 # fdesc: check external lib file if it exist and can works.
912 # save checking resualt into build-pkg config file.
921 # fsyntax: dep_syshdr_chk
922 # fdesc: check system .h file if it exist.