中山野鬼 linux 下 C 编程和make的方法 (七、补充,模块化项目组织的Makefil...

正题谈到模块化的设计方式。这里给出模块化Makefile模板的创建脚本的改良方案。先说说目标。然后贴上源码,最后给出一些简单的解释。如果有网友对特别是脚本的实现方法,有更好的方式,记得给个指正。我一向,“不怕被鄙视,就怕自认为一切OK。”
    谈目标前,得再谈一下程序开发,或者软件设计。编写程序,最终形成客户需要的软件,需要经过很多步骤。去掉后面包装的事情,仅谈开发,也包括问题细化,原型验证,平台验证,整体优化四个阶段。不过阶段与阶段之间,不是因果关系,有时甚至是递归。
    什么是问题细化。假设客户说,我要吃东西。于是乎,你随地捡起块石头放桌上。客户说,不行,第一,我要吃食物(靠不早说,只不过他以为你知道),第二刚拉过便便,我需要工具而不是用手。但至少现在明确了,需要个桌子,椅子,而且他已经就位了。
    于是乎,你拖来一头猪,外加一把菜刀。客户说,不行,第一,猪是生的,(死活暂不谈),第二,菜刀给我也没有用。
    于是乎,你切成块,该煮的还要煮,遇到色香味缺一的,还要回炉。
    软件开发,准确说是客户需求实现,和其他很多服务类似,例如“个人艺术照”,无论是定制,还是产品化。只不过后者是先将客户一棒子敲晕,后收钱。前者是不停的按客户需求实现,等到客户没时间了,算了解。
    因此,问题的细化,有时不单单是设计人员的问题,和客户本身也有关系。而原型验证,平台验证是由具体问题需求所产生的。而整体优化,这属于一个客户体验度 的问题。或者是问题本身。例如客户觉得原先的方案慢了。那么客户的基础目标已经全部确立,原先的方案就OK。只是体验度目标,客户要求调整。不过需要明 确,这两类的目标有很大差异。基础目标是客户的问题本身,体验度属于实现方案客户体验的问题。因此,后者是明确建立在前者基础之上的。
    说了这么多,是希望将整体优化,和其他工作区别开来。优化属于客户满意度的问题。而模块化项目组织,只是解决客户的基础问题而不是体验度。但是模块化的项目组织好坏,直接影响后期整体优化的项目开展进度。
    而对于开发者而言,还有一个和客户没有关系的问题,如何提高工作效率,降低重复性劳动。在面向对象问题上,采用类复用的技术,而在C语言开发中,模块化的方式,则更为有效。采用模块化开发至少有以下几个优势:
    1、问题分而治之。有效降低局部问题的扩散性的情况。
    2、复用技术,可以将设计工作重点集中在目标的特性上。
    3、对系统的理解更为容易,便于后期客户目标调整时的方案调整。
    针对上述好处,由此确定出模块化Makefile创建模板的目标。需要达到以下几个要求。
    1、每个目录组成一个模块。当然包括这个目录下的子模块。
    2、模块模板创建脚本能自动生成模块,包括目录,模块接口C文件,对应头文件,对应测试文件。对应当前默认Makefile。
    3、对应Makefile可以具备递归处理所依赖的子模块的make工作。

    由此我修正了前面的create_module.sh 的脚本。如下。

001#!/bin/bash
002MODULE_PATH=$1
003MODULE_NAME=$1
004 
005SRC_DIR_NAME=src
006INC_DIR_NAME=inc
007BIN_DIR_NAME=bin
008OBJ_DIR_NAME=obj
009C_FILE_SUFFIX=.c
010H_FILE_SUFFIX=.h
011TEST_FILE_SUFFIX=.t
012MAKE_FILE_SUFFIX=.m
013CREATE_FILE_FLAG=-f
014CREATE_H_FILE_FLAG=-h
015CREATE_TEST_FILE_FLAG=-t
016CREATE_MAKEFILE_FILE=-m
017CREATE_DEP_FILE=-d
018OVERWRITE_FILE=0
019NOT_OVERWRITE_FILE=1
020 
021create_mkdir(){
022    mkdir $1 > /dev/null 2>&1
023    if [ $? = 0 ];then 
024        echo /$1 had created
025        return 1
026    else
027        if [ -d $1 ];then
028            echo /$1 had exist
029            return 0
030        else
031            echo "could not create directory "/$1
032            exit
033        fi
034    fi
035 
036}
037check_file_exist(){
038    if [ -e $1 ];then
039        while :;do
040            echo -n "the $1 had exist , do you want to overwrite?(y(Y) done:n(N) not:e(E) exit) : "
041            read check_file_exist_ans
042            case $check_file_exist_ans in
043            y|Y)
044                echo you answer y
045                return $OVERWRITE_FILE
046            ;;
047            n|N)
048                echo you answer n
049                return $NOT_OVERWRITE_FILE
050            ;;
051            e|E)
052                exit
053            ;;
054            *)
055                echo  "fuck ,i need you correct answer!"
056            esac
057        done
058    else
059        return $OVERWRITE_FILE
060    fi
061}
062CREATE_NEW_FLIE=0
063CREATE_NEW_FILE_ERROR=1
064EXIST_FILE=2
065INSERT_FILE_CON=""
066 
067get_c_init_context(){
068#$1 path/filename.ext
069#$2 filename
070    INSERT_FILE_CON="/***************\n$1\n by luckystar\n ***************/\n"
071    INSERT_FILE_CON+="#include \"$2.h\"\n"
072    INSERT_FILE_CON+="static int $2_flag =0;\n"
073    INSERT_FILE_CON+="\nvoid $2_init(void){\n"
074    INSERT_FILE_CON+="\tif ($2_flag) {\n\t\t//log(\"module inited..\",X);\n\t\treturn;\n\t}\n"
075    INSERT_FILE_CON+="\t$2_flag = 1;\n"
076    INSERT_FILE_CON+="\t//todo:module init...\n\n}\n"
077#up is create module_init func 
078    INSERT_FILE_CON+="\nvoid $2_destory(void){\n"
079    INSERT_FILE_CON+="\tif (!$2_flag) {\n\t\t//log(\"module not inited..\",X);\n\t\treturn;\n\t}\n"
080    INSERT_FILE_CON+="\t$2_flag = 0;\n"
081    INSERT_FILE_CON+="\t//todo:module destory...\n\n}\n"
082#up is create module_destory func
083}
084 
085get_h_init_context(){
086#$1 path/filename.ext
087#$2 filename
088    INSERT_FILE_CON="#ifndef _$2_H_\n#define _$2_H_\n"
089    INSERT_FILE_CON+="\n//ins_inc_file\n"
090    INSERT_FILE_CON+="\n//ins_typedef_def\n"
091    INSERT_FILE_CON+="\n//ins_def\n"
092    INSERT_FILE_CON+="\n//ins_func_declare\n"
093    INSERT_FILE_CON+="\n\n"
094    INSERT_FILE_CON+="#endif //_$2_H_\n"       
095}
096get_test_init_context(){
097#$1 filename
098#$2 libname
099    INSERT_FILE_CON="#include \"$2.h\"\n"
100    INSERT_FILE_CON+="#include <stdio.h>\n"
101    INSERT_FILE_CON+="\n\n"
102    INSERT_FILE_CON+="int main(int argc,char *argv[]){\n"
103    INSERT_FILE_CON+="\tprintf(\"hello test_$2_main now run...\\\n\");\n"  
104    INSERT_FILE_CON+="\t$2_init();\n"
105    INSERT_FILE_CON+="\t$2_destory();\n"
106    INSERT_FILE_CON+="\tprintf(\"hello test_$2_main now exit...\\\n\");\n"     
107    INSERT_FILE_CON+="\treturn 0;\n"
108    INSERT_FILE_CON+="}\n"     
109}
110get_make_init_context(){
111#$1 module_name
112INSERT_FILE_CON="SRC_PATH=src/\n"
113INSERT_FILE_CON+="INC_PATH=inc/\n"
114INSERT_FILE_CON+="OBJ_PATH=obj/\n"
115INSERT_FILE_CON+="BIN_PATH=bin/\n"
116INSERT_FILE_CON+="MODULE_NAME = $1\n"
117INSERT_FILE_CON+="MODULE_FILE = \$(MODULE_NAME) \n"
118INSERT_FILE_CON+="MODULE_INC =\n\n\n\n"
119INSERT_FILE_CON+="MODULE_T = test_\$(MODULE_NAME)_main\n"
120INSERT_FILE_CON+="MODULE_TS = \$(SRC_PATH)\$(MODULE_T).c\n"
121INSERT_FILE_CON+="MODULE_TB = \$(BIN_PATH)\$(MODULE_T)\n"
122INSERT_FILE_CON+="MODULE_SUB =\n\n\n"
123INSERT_FILE_CON+="MODULE_SRC = \$(addsuffix .c,\$(addprefix \$(SRC_PATH),\$(MODULE_FILE)))\n"
124INSERT_FILE_CON+="MODULE_OBJ = \$(addsuffix .o,\$(addprefix \$(OBJ_PATH),\$(MODULE_FILE)))\n"
125INSERT_FILE_CON+="MODULE_INC += \$(addsuffix .h,\$(addprefix \$(INC_PATH),\$(MODULE_FILE)))\n"
126INSERT_FILE_CON+="MODULE_LIB = lib\$(MODULE_NAME).a\n"
127INSERT_FILE_CON+="MODULE_BIN = \$(BIN_PATH)\$(MODULE_LIB)\n"
128INSERT_FILE_CON+="MODULE_SUB_LIB = \$(foreach var,\$(MODULE_SUB),\$(var)/\$(BIN_PATH)lib\$(var).a)\n"
129INSERT_FILE_CON+="MODULE_SUB_INC =\n\n\n"
130INSERT_FILE_CON+="test:\n\n\n\n"
131INSERT_FILE_CON+="ifndef MODULE_DEP\n"
132INSERT_FILE_CON+="\$(error No Dependence)\n"
133INSERT_FILE_CON+="endif\n"
134INSERT_FILE_CON+="\$(foreach var,\$(MODULE_FILE),\$(eval \$(OBJ_PATH)\$(var).o:\$(SRC_PATH)\$(var).c  \$(INC_PATH)\$(var).h))\n\n"
135INSERT_FILE_CON+="RM = -rm -f\n\n"
136INSERT_FILE_CON+="test:all \$(MODULE_TB)\n\n"
137INSERT_FILE_CON+="\$(MODULE_TB):\$(MODULE_TS)\n"
138INSERT_FILE_CON+="  gcc -O2 -I\$(MODULE_SUB_INC) -I\$(INC_PATH) \$^ -L\$(BIN_PATH) -l\$(MODULE_NAME)    -o \$@\n\n\n"
139INSERT_FILE_CON+="\$(MODULE_OBJ):\n"
140INSERT_FILE_CON+="  gcc  -I\$(MODULE_SUB_INC) -I\$(INC_PATH) -c \$< -o \$@\n\n\n"
141INSERT_FILE_CON+="\$(MODULE_BIN):\$(MODULE_OBJ) \$(MODULE_SUB_LIB)\n"
142INSERT_FILE_CON+="  <a href="http://my.oschina.net/yuning0502" target="_blank" rel="nofollow">@echo</a> module bin \$@\n"
143INSERT_FILE_CON+="  ar -r \$@ \$(MODULE_OBJ)\n"
144INSERT_FILE_CON+="  ar -q \$@ \$(MODULE_SUB_LIB)\n\n"
145INSERT_FILE_CON+="all:\$(MODULE_BIN)\n\n"  
146INSERT_FILE_CON+="\$(MODULE_SUB_LIB):   \$(MODULE_SUB)\n\n"
147INSERT_FILE_CON+="clean: \$(MODULE_SUB) clean_self\n\n"
148INSERT_FILE_CON+="clean_self:\n"
149INSERT_FILE_CON+="  \$(RM) \$(MODULE_OBJ)\n"
150INSERT_FILE_CON+="  \$(RM) \$(MODULE_BIN)\n"
151INSERT_FILE_CON+="  \$(RM) \$(MODULE_TB)\n\n"
152INSERT_FILE_CON+="rebuild:clean module_dep all\n\n"
153INSERT_FILE_CON+="\$(MODULE_SUB):\n"
154INSERT_FILE_CON+="  <a href="http://my.oschina.net/yuning0502" target="_blank" rel="nofollow">@echo</a> \"***************  todo Module SUB\" \$@  \"*****************\"\n"
155INSERT_FILE_CON+="  - \$(MAKE) -C \$@ \$(MAKECMDGOALS)\n\n\n"
156INSERT_FILE_CON+="#module_dep:\n"
157INSERT_FILE_CON+="# gcc -I\$(MODULE_SUB_INC) -I\$(INC_PATH) -MM \$(MODULE_SRC)  > \$(MODULE_NAME).d\n"
158INSERT_FILE_CON+="# sed -i '1 i\$(MODULE_NAME)_DEP = \$(MODULE_NAME)_DEP' \$(MODULE_NAME).d\n"
159INSERT_FILE_CON+="# sed -i '/.o:/ s,^,\$(OBJ_PATH),' \$(MODULE_NAME).d\n\n"
160INSERT_FILE_CON+=".PHONY: test all clean clean_self rebuild \$(MODULE_SUB) module_dep\n"
161}
162insert_file_tmp(){
163#$1 path/filename.ext
164#$2 filename
165#$3 ext mode
166    case $3 in
167    $C_FILE_SUFFIX)
168    get_c_init_context $1 $2
169    ;;
170    $H_FILE_SUFFIX)
171    get_h_init_context $1 $2
172    ;;
173    $TEST_FILE_SUFFIX)
174    get_test_init_context $4 $2
175    ;;
176    $MAKE_FILE_SUFFIX)
177    get_make_init_context $2
178    ;;
179    esac
180    sed  -i "a\\$INSERT_FILE_CON" $1
181     
182}
183create_Makefile(){
184#$1 makefile name
185    NEW_FILENAME="Makefile"
186    check_file_exist $NEW_FILENAME
187    echo > $NEW_FILENAME
188    if [ $? = $OVERWRITE_FILE ];then
189        echo > $NEW_FILENAME
190        insert_file_tmp $NEW_FILENAME $MODULE_NAME $MAKE_FILE_SUFFIX
191        echo create /$MODULE_PATH/$NEW_FILENAME files
192        return $CREATE_NEW_FILE
193    else
194        return $EXIST_FILE
195    fi 
196         
197}
198create_file_in_sub_dir(){
199     
200    if [ -d $1 ];then
201        if [ $3 = $TEST_FILE_SUFFIX ]; then
202        NEW_FILENAME=$1/test_$4_main.c
203        else
204        NEW_FILENAME=$1/$2$3
205        fi
206        check_file_exist $NEW_FILENAME
207        if [ $? = $OVERWRITE_FILE ];then
208            echo > $NEW_FILENAME
209            insert_file_tmp $NEW_FILENAME $2 $3 $4
210            echo create /$MODULE_PATH/$NEW_FILENAME files
211            return $CREATE_NEW_FILE
212        else
213            return $EXIST_FILE
214        fi
215    else
216        echo  /$MODULE_PATH/$1 is not directory, create_file not continue...
217        return $CREATE_NEW_FILE_ERROR
218        #not exit , continue done the other cmd
219    fi
220}
221MODULE_FILE=MODULE_FILE
222MODULE_SRC=""
223OBJ_PATH=OBJ_PATH
224SRC_PATH=SRC_PATH
225MODULE_NAME_DEP_CHECK="ifndef MODULE_DEP"
226RETURN_VALUE=
227 
228read_value_from_file(){
229#$1 filename $s2 valuename $3 is not add
230#get return ,need used RETURN_VALUE
231var=$2
232mode=
233 
234    unset RETURN_VALUE
235 
236    while read var;do
237         
238        case $var in
239        \#*)    ;;
240        \.*)    ;;
241        *)
242         
243        var=`echo $var | sed -n "/^$2[\ ]*=/p"`
244        #get name  += value
245        #name ?= value .....
246        if [ -z "$var" ]; then
247            continue;
248        fi
249        #echo step1 $var
250        mode=`echo $var | sed -n "/+=/p"`
251        var=`echo $var | sed -n "s/^.*=//p"`
252        if [ -z "$mode" ]; then
253            RETURN_VALUE=$var
254            continue;
255        else
256            if [ 3 -le $# ]; then
257            RETURN_VALUE=${RETURN_VALUE}${var}
258            fi
259        fi
260        #echo step2 $RETURN_VALUE
261 
262        esac
263    done < $1
264#   echo get return_value $RETURN_VALUE
265    return
266}
267get_first_data(){
268    echo first data $1
269    return $1
270}
271get_last_data(){
272    while [ 1 -lt $# ];do
273        shift
274    done
275    echo last1 data $1
276    return $1
277}
278cut_lines_in_file(){
279#cut from $2 line to $3 line in file $1
280#not check $1 file exist ,static func only
281first=
282last1=
283    #echo $2 $3
284    unset first
285    unset last1
286    first=`sed -n "/$2/=" $1`
287    last1=`sed -n "/$3/=" $1`
288    if [ -n "$first" -a -n "$last1" ]; then
289        get_first_data $first
290        first=$?
291        get_last_data $last1
292        last1=`expr $? - 1`
293        echo $first ${last1} $1
294        sed -i "${first},${last1}d" $1
295    fi
296    return
297      
298}
299get_sub_module(){
300    #$1 Makefile file name
301    if [ -e $MAKEFILE ];then
302        echo "read info form $MAKEFILE ..."
303    else
304        echo "Makefile(${MAKEFILE}) not exist!"
305        unset RETURN_VALUE
306        return
307    fi
308    read_value_from_file $1 "MODULE_SUB"
309#   echo $RETURN_VALUE
310    exit   
311}
312cut_value_from_const(){
313#$1 if have $(XXX) ,will cut
314    RETURN_VALUE=`echo $RETURN_VALUE | sed -n "s/[\$][(][^)]*[)]/ /p"`
315     
316}
317MODULE_INC=
318adjust_MODULE_INC(){
319    MODULE_INC=`echo $MODULE_INC|sed -n "s/[^ ]*/ -I&/gp"`
320}
321MODULE_SUB_ALL_PATH=
322get_inc_path(){
323path_tmp=
324    echo "all subdir is: " $@
325    while [ 1 -le $# ] ;do
326         
327        path_tmp=`echo $1 | sed -n "s/^.*$/ &\Makefile/p"`
328        echo "ready get file is :" $path_tmp
329        read_value_from_file $path_tmp "MODULE_SUB" "+"
330        MODULE_SUB1=$RETURN_VALUE
331         
332        if [ -z "$MODULE_SUB1" ]; then
333            MODULE_SUB_ALL_PATH+=${1}
334            echo "No MODULE_SUB more..." $1
335            shift
336            continue;
337        fi
338        MODULE_SUB1=`echo $MODULE_SUB1 | sed -e "/[^ ]*/s,,$1&\/,g"`
339        MODULE_SUB_ALL_PATH+=$1
340        get_inc_path $MODULE_SUB1
341        shift
342    done
343}
344get_all_INC_path(){
345    unset MODULE_SUB_ALL_PATH
346    get_inc_path "../$MODULE_NAME/"
347    MODULE_SUB_ALL_PATH=`echo $MODULE_SUB_ALL_PATH | sed -n "/[\.][\.][]\/]/s,, &,gp"`
348    MODULE_SUB_ALL_PATH=`echo $MODULE_SUB_ALL_PATH | sed -n "/[\.][\.][]\/][^\.^ ]*/s,, -I&inc,gp"`
349    echo "all path is : " $MODULE_SUB_ALL_PATH
350    #exit  
351}
352create_depend_file(){
353#use gcc -MM create dependfile 
354#$1 module_name $2 makefile name not support!!
355    #if [ 2 -le $# ];then
356    #   MAKEFILE=$2
357    #else
358        MAKEFILE=Makefile
359    #fi
360     
361 
362    #get_sub_module $MAKEFILE
363#   echo $MAKEFILE set MAKEFILE default is Makefile
364    if [ -e $MAKEFILE ];then
365        echo "read info form $MAKEFILE ..."
366    else
367        echo "Makefile(${MAKEFILE}) not exist!"
368        exit
369    fi
370    read_value_from_file $MAKEFILE $SRC_PATH
371    SRC_PATH=$RETURN_VALUE
372    read_value_from_file $MAKEFILE $OBJ_PATH
373    OBJ_PATH=$RETURN_VALUE 
374    read_value_from_file $MAKEFILE $MODULE_FILE "+"
375    echo return_cut begin $RETURN_VALUE
376    cut_value_from_const $RETURN_VALUE
377    echo return_cut end $RETURN_VALUE
378    MODULE_FILE=${MODULE_NAME}${RETURN_VALUE}
379    MODULE_SRC=`echo $MODULE_FILE | sed -e "/[^ ]*/s,,$SRC_PATH&.c,g"`
380    echo "MODULE INFO:"
381    echo "SRC_PATH = "$SRC_PATH
382    echo "OBJ_PATH = "$SRC_PATH
383    echo "MODULE_FILE = "$MODULE_FILE
384    echo "MODULE_SRC = "$MODULE_SRC
385    get_all_INC_path
386    gcc $MODULE_SUB_ALL_PATH  -MM $MODULE_SRC > $MODULE_NAME.d
387    sed -i "1 iMODULE_DEP = ${MODULE_NAME}_DEP" $MODULE_NAME.d
388    sed -i "/.o:/ s,^,${OBJ_PATH}," $MODULE_NAME.d
389    cut_lines_in_file $MAKEFILE ${MODULE_NAME}_DEP  "$MODULE_NAME_DEP_CHECK"
390    echo "Dependinfo is :"
391    cat  $MODULE_NAME.d
392    echo "Dependinfo end"
393    sed -i "/ifndef[ ]*MODULE_DEP/i ifndef__TMP MODULE_DEP" $MAKEFILE
394    sed -i "/ifndef__TMP[ ]*MODULE_DEP/r $MODULE_NAME.d" $MAKEFILE
395    sed -i "/ifndef__TMP[ ]*MODULE_DEP/d"  $MAKEFILE
396    sed -i "/^MODULE_SUB_INC.*$/s,,MODULE_SUB_INC = $MODULE_SUB_ALL_PATH," $MAKEFILE
397    return
398 
399}
400 
401check_other_cmd(){
402#MODULE_INC="a b/c/d e"
403#   echo $MODULE_INC
404#   adjust_MODULE_INC
405#   echo $MODULE_INC
406#   exit
407    #MODULE_SUB= read_value_from_file "Makefile" "MODULE_SUB" "+"
408 
409    #echo $MODULE_SUB1
410    #exit
411 
412     
413while [ 2 -le $# ];do
414    case $2 in
415    $CREATE_FILE_FLAG)
416        shift
417        create_file_in_sub_dir $SRC_DIR_NAME $2 $C_FILE_SUFFIX #$C_FILE_TMP
418        create_file_in_sub_dir $INC_DIR_NAME $2 $H_FILE_SUFFIX #$H_FILE_TMP
419         
420        #create_file_in_sub_dir $LOG_DIR_NAME $2 $LOG_FILE_SUFFIX
421         
422    ;;
423    $CREATE_TEST_FILE_FLAG)
424        shift
425        create_file_in_sub_dir $SRC_DIR_NAME $2 $TEST_FILE_SUFFIX  $3
426        shift
427         
428        ;;
429    $CREATE_H_FILE_FLAG)
430        shift
431        create_file_in_sub_dir $INC_DIR_NAME $2 $H_FILE_SUFFIX #$H_FILE_TMP
432        ;; 
433    $CREATE_DEP_FILE)
434        #shift
435        create_depend_file $MODULE_NAME #$2
436        ;;
437    $CREATE_MAKEFILE_FILE)
438        #shift
439        create_Makefile $MODULE_NAME
440        ;;
441    *)
442        ;;
443       #    echo $2" test "
444    esac
445        shift
446done
447    exit
448}
449echo $MODULE_PATH
450 
451create_mkdir $MODULE_PATH
452is_created=$?
453echo $is_created
454 
455    MODULE_NAME=`echo $MODULE_PATH|sed -e "s/^.*[\/]//"`
456 
457if [ -d $MODULE_PATH ];then
458    cd $MODULE_PATH
459    create_mkdir $SRC_DIR_NAME
460    create_mkdir $INC_DIR_NAME
461    create_mkdir $BIN_DIR_NAME
462    create_mkdir $OBJ_DIR_NAME
463     
464    if [ "$is_created" -eq "1" ];then
465    #create_Makefile $MODULE_NAME
466    check_other_cmd $@ -f $MODULE_NAME -t $MODULE_NAME $MODULE_NAME -m -d
467    else
468    check_other_cmd $@
469    fi
470else
471    echo $MODULE_NAME is not directory ,could not continue...  
472    exit
473fi

需要解释一下修正的几个部分。
    1、./create_module name 时,如果 name这个目录不存在时,处理以下工作。
     1、创建 name  name/inc name/src name/obj name/bin 5个目录。
    2、创建 name/src/name.c name/inc/name.h name/src/test_name_main.c 3个C语言文件。
    3、创建 name/Makefile 这个Makefile。同时将上述3个C语言文件的对应信息加载进去。
    4、修正Makefile的文件依赖规则,通过读取3步骤中的Makefile文件里的MODULE_FILE(这里仅针对 C文件),使用gcc -MM。(哈有人要骂我了。因为我前面才说不要依赖gcc -MM,我的理由是此处是为了给予方便)形成依赖规则,保存在 name/name.d内。同时将name.d内的内容,扩充到 name/Makefile的内容中去。
    当你执行
    ./create_moudle learn_make 这里用learn_make作为一个典型模块举例。
    你可以
    cd learn_make
    make
    此时make 执行 make test的工作。完成所有的库的编译,并完成 test_learn_make_main.c的对应编译。
    执行
    bin/test_learn_make_main
    此时会出现对应打印信息。你可以通过观察 test_learn_make_main.c的源码理解。
    以上是针对一个模块。你可以继续,如下
    ./create_module learn_make/data_struct
    此时会和 create_module learn_make一样,完成上述动作。同时你进入
    cd learn_make/data_struct
    make
    bin/test_data_struct_main
    也可以。
    不过这个只解决了如何在模块下面创建子模块的问题。
    有另外个问题。此时learn_make和 data_struct并没有关联起来。你需要在
    learn_make/Makefile的文件中,找到
    MODULE_SUB= 的位置,此处添加data_struct,该行的处理结果如下
    MODULE_SUB= data_struct 这个作用下面会说到。如果不这么关联,Makefile只能递归执行所有模块的独自编译和.a 的依次合并。
    此时,保存退出。你进入learn_make目录下,
    此时
    make
    实际执行make test。
    此时,make会将learn_make 和data_struct均make一遍,同时Makefile文件保持一个递归模式,将data_struct/bin/libdata_struct.a 并入到当前bin/liblearn_make.a中。
    由此完成每个子模块内的.a文件,如何被最上层模块使用的问题。但问题只完成了一半。当你在learn_make/src/learn_make.c 或者learn_make/src/test_learn_make_main.c中,尝试 #include "data_struct.h"时,gcc会出错。因此你需要使用create_module的另一个自动检测。
    ./create_module.sh learn_make -d
    但这样并不会立刻有效果。是因为,这个工作我实现的方法是,依赖于对/learn_make/Makefile里,MODULE_SUB的变量进行检查。以递归的寻找所有的inc目录。
    如上方法,你需要将learn_make/Makefile的文件,在 MODULE_SUB=这行进行修改,最终效果如下
    MODULE_SUB= data_struct
    此时,你执行
    ./create_module.sh learn_make -d
    则对应的文件依赖性的关系,会自动创建在 /learn_make/Makefile 中,同时,对应也修改了Makefile 里 MODULE_SUB_INC的变量内容。
    当然你会发现,这里多了一个-I../learn_make/inc 这么变态的内容,而我的Makefile的内部模板在gcc -c 中本身包行了 -Iinc。这是为了简单的递归查找 Makefile的文件时的遗留问题,我暂时不做此修正了。
    现在你会发现,以上的工作,已经可以使得模块调用子模块存在自动化的操作。
    当你进入每个目录时,均是针对当前这个目录对应的模块处理。同时你可以通过COPY其他模块到本模块下,进行操作。但是有个很致命的问题。假设你现在有如下的模块
    A/B/C
    也即A 模块下有B ,B 模块下有C 。此时,你将 C的整体目录COPY到A目录下,由此,A目录下存在两个C模块。则会导致一个非常头疼的事情。即库函数冲突。
因为目前的操作,是将 C的.a,合并到B的.a,B的.a合并到A的.a中。而当A下还有个C。则出现同样C模块的函数,在最终A的库中存在重名问题。

    解决这个问题,有两个操作方式。
    1、库化。将C的.a不是依次继承到最上层的.a中,而是独立放在一个A,B都能看到的lib 目录里,同时 .h放置在一个include的目录里,用于给A调用。和传统的库一样。但是这是基于C已经没有问题下。此时C模块已经不属于开发态。
    2、强制A模块禁止直接挂载C这个目录,如果C的目录被A的子模块使用时。但这个当B模块被拿走时,A又郁闷了。此时,则当C模块处于开发态时,B拿走,需要将B下的所有子模块,强制挂载到A下,如果C模块不属于开发态时,则按照1的方案实施。
    需要注意,上述这个问题,在目前的create_module脚本中,并没有处理。
    目前只是解决,假设存在,A,AA两个模块。当A模块下的B子模块被AA也需要使用。则可以采用COPY B目录下所有内容。到AA下,并修改AA/Makefile,MODULE_SUB 加上 B。随后执行 ./create_module AA -d 则,B模块会自动作为AA的依赖,并入到AA的Makefile里。

    同样需要注意的Makefile内的细节问题。
    Makefile 目前存在依赖冗余,就是一个相同依赖被几个不同地方描述。这个暂时不考虑。提一下一些变量的内容含义。
    SRC_PATH=src/
    INC_PATH=inc/
    OBJ_PATH=obj/
    BIN_PATH=bin/
    MODULE_NAME = learn_make
    以上5个,原则上,禁止修改,此是和

   $./create_module learn_make

   创建模块形成目录有关
MODULE_FILE = $(MODULE_NAME)
    这里可以后续增加当前模块下,新的C文件的文件名,但别加后缀以及路径。对应在MODULE_SRC MODULE_INC中,会自动增加同名的.c和同名的.h
MODULE_INC =
    这里只增加只有头文件,没有实际C文件的独立头文件名。但是此时需要注意,例如你要增加个type.h则需要写为 $(INC_PATH)type.h。
MODULE_T = test_$(MODULE_NAME)_main
    这个是定义该模块的唯一测试主程序。模块本身并不可直接编译运行。模块内部不存在main函数。这个唯一测试文件名,是由./create_module 创建,当然你可以自己任意修改成自己的名字。但是对应的 src/下的C文件名也需要修改。当然此处一样,不需要加.c后缀。
MODULE_TS = $(SRC_PATH)$(MODULE_T).c
MODULE_TB = $(BIN_PATH)$(MODULE_T)
    这两个不许要修改,是根据测试文件本身,获取测试文件C源文件全名,和输出执行程序名。在bin/下。
MODULE_SUB =
    这里是用于添加子模块名称。不需要路径。同时只需要当前目录下直接关联的子模块,对于孙子等等模块,Makefile描述中包含了递归自动处理的部分。这 样处理也希望开发人员,只关注当前模块和当前直接调用的模块的关系,而不要关注子模块内部。当然前面说的父子同调用一个孙子的情况另谈。

MODULE_SRC = $(addsuffix .c,$(addprefix $(SRC_PATH),$(MODULE_FILE)))
MODULE_OBJ = $(addsuffix .o,$(addprefix $(OBJ_PATH),$(MODULE_FILE)))
MODULE_INC += $(addsuffix .h,$(addprefix $(INC_PATH),$(MODULE_FILE)))
MODULE_LIB = lib$(MODULE_NAME).a
MODULE_BIN = $(BIN_PATH)$(MODULE_LIB)
MODULE_SUB_LIB = $(foreach var,$(MODULE_SUB),$(var)/$(BIN_PATH)lib$(var).a)
MODULE_SUB_INC = 
    以上均不要改动,除非你要改动下面Makefile的依赖规则或目标

MODULE_DEP = learn_make_DEP
..
ifndef MODULE_DEP
$(error No Dependence)
endif
以上需要注意,均是自动生成的。
ifndef MODULE_DEP
$(error No Dependence)
endif
是通过创建Makefile的模板自动添加的,目的是防止没有O文件,C文件依赖描述时,make的依赖出现遗漏。
而MODULE_DEP = learn_make_DEP 是通过 ./create_module learn_make -d 这个操作实现的。这个操作前面说过。根据MODULE_SUB,获取头文件信息,并针对当前模块的源进行 gcc -MM。随后将依赖填写到这里,并自动加上 MODULE_DEP = learn_make_DEP
但需要非常注意的一点。gcc -MM 并没有递归实现每个子模块的依赖。因为我的逻辑是,当前模块的依赖自动生成,只是针对当前模块的情况,而子模块,假设 learn_make/data_struct ,你需要 ./create_module learn_make/data_struct -d来手动完成。因为你尝试在learn_make/data_struct内增加一个C文件,或#include的动作,此属于data_struct 本身,而不属于learn_make本身。各个模块做各个模块的事情嘛。呵呵。
以下给出create_module脚本的参数和举例
./create_module module_name
会自动创建目录,某块接口C,头文件, MAKEFILE和依赖
此处会自动调用 -d -m -f module_name -t module_name module_name
./create_module module_name -d
-d 自动刷新依赖
./create_module module_name -m
-m 重建MAKEFILE 但不会处理依赖
-f name 生成name.c 的C文件,对应有name.h的头文件。
-h name 生成name.h的头文件
-t name1 name2 生成 test_name2_main.c的 C文件,不会生成头文件,但会在 test_name2_main.c 自动增加 #include "name1.h"

  • 中山野鬼:SORRY,Makefile有个依赖缺失的错误,在137行。原先的INSERT_FILE_CON+="\$(MODULE_TB):\$(MODULE_TS)\n"需要修改为: INSERT_FILE_CON+="\$(MODULE_TB):\$(MODULE_TS) \$(MODULE_TB)\n" 否则,模块文件更新后,make test并不会重新链接模块。 删除 3个月前
  • 中山野鬼:sorry ,又错了。笔误,笔误,哈哈。 对应的修改应该为 INSERT_FILE_CON+="\$(MODULE_TB):\$(MODULE_TS) \$(MODULE_BIN)\n" 删除 3个月前

后续实际使用,又发现错误, 已经做了些小操作的增补,当然代码越来越不成样子了。(2010年7月)以下给出目前代码

 #!/bin/bash

002MODULE_PATH=$1
003MODULE_NAME=$1
004 
005SRC_DIR_NAME=src
006INC_DIR_NAME=inc
007BIN_DIR_NAME=bin
008OBJ_DIR_NAME=obj
009INCLUDE_DIR_NAME=include
010LIB_DIR_NAME=lib
011C_FILE_SUFFIX=.c
012H_FILE_SUFFIX=.h
013TEST_FILE_SUFFIX=.t
014MAKE_FILE_SUFFIX=.m
015CREATE_FILE_FLAG=-f
016CREATE_H_FILE_FLAG=-h
017CREATE_TEST_FILE_FLAG=-t
018CREATE_MAKEFILE_FILE=-m
019CREATE_DEP_FILE=-d
020OVERWRITE_FILE=0
021NOT_OVERWRITE_FILE=1
022 
023create_mkdir(){
024    mkdir $1 > /dev/null 2>&1
025    if [ $? = 0 ];then 
026        echo /$1 had created
027        return 1
028    else
029        if [ -d $1 ];then
030            echo /$1 had exist
031            return 0
032        else
033            echo "could not create directory "/$1
034            exit
035        fi
036    fi
037 
038}
039check_file_exist(){
040    if [ -e $1 ];then
041        while :;do
042            echo -n "the $1 had exist , do you want to overwrite?(y(Y) done:n(N) not:e(E) exit) : "
043            read check_file_exist_ans
044            case $check_file_exist_ans in
045            y|Y)
046                echo you answer y
047                return $OVERWRITE_FILE
048            ;;
049            n|N)
050                echo you answer n
051                return $NOT_OVERWRITE_FILE
052            ;;
053            e|E)
054                exit
055            ;;
056            *)
057                echo  "fuck ,i need you correct answer!"
058            esac
059        done
060    else
061        return $OVERWRITE_FILE
062    fi
063}
064CREATE_NEW_FLIE=0
065CREATE_NEW_FILE_ERROR=1
066EXIST_FILE=2
067INSERT_FILE_CON=""
068 
069get_c_init_context(){
070#$1 path/filename.ext
071#$2 filename
072    INSERT_FILE_CON="/***************\n$1\n by luckystar\n ***************/\n"
073    INSERT_FILE_CON+="#include \"$2.h\"\n"
074    INSERT_FILE_CON+="static int $2_flag =0;\n"
075    INSERT_FILE_CON+="\nvoid $2_init(void*pv){\n"
076    INSERT_FILE_CON+="\tif ($2_flag) {\n\t\t//log(\"module inited..\",X);\n\t\treturn;\n\t}\n"
077    INSERT_FILE_CON+="\t$2_flag = 1;\n"
078    INSERT_FILE_CON+="\t//todo:module init...\n\n}\n"
079#up is create module_init func 
080    INSERT_FILE_CON+="\nvoid $2_destory(void){\n"
081    INSERT_FILE_CON+="\tif (!$2_flag) {\n\t\t//log(\"module not inited..\",X);\n\t\treturn;\n\t}\n"
082    INSERT_FILE_CON+="\t$2_flag = 0;\n"
083    INSERT_FILE_CON+="\t//todo:module destory...\n\n}\n"
084#up is create module_destory func
085}
086 
087get_h_init_context(){
088#$1 path/filename.ext
089#$2 filename
090    INSERT_FILE_CON="#ifndef _$2_H_\n#define _$2_H_\n"
091    INSERT_FILE_CON+="\n//ins_inc_file\n"
092    INSERT_FILE_CON+="\n//ins_typedef_def\n"
093    INSERT_FILE_CON+="\n//ins_def\n"
094    INSERT_FILE_CON+="\n//ins_func_declare\n"
095    INSERT_FILE_CON+="void $2_init(void*);\n"
096    INSERT_FILE_CON+="void $2_destory(void);\n"
097    INSERT_FILE_CON+="\n\n"
098    INSERT_FILE_CON+="#endif //_$2_H_\n"       
099}
100get_test_init_context(){
101#$1 filename
102#$2 libname
103    INSERT_FILE_CON="#include \"$2.h\"\n"
104    INSERT_FILE_CON+="#include <stdio.h>\n"
105    INSERT_FILE_CON+="\n\n"
106    INSERT_FILE_CON+="int main(int argc,char *argv[]){\n"
107    INSERT_FILE_CON+="\tprintf(\"hello test_$2_main now run...\\\n\");\n"  
108    INSERT_FILE_CON+="\t$2_init(0);\n"
109    INSERT_FILE_CON+="\t$2_destory();\n"
110    INSERT_FILE_CON+="\tprintf(\"hello test_$2_main now exit...\\\n\");\n"     
111    INSERT_FILE_CON+="\treturn 0;\n"
112    INSERT_FILE_CON+="}\n"     
113}
114get_make_init_context(){
115#$1 module_name
116INSERT_FILE_CON="SRC_PATH=src/\n"
117INSERT_FILE_CON+="INC_PATH=inc/\n"
118INSERT_FILE_CON+="OBJ_PATH=obj/\n"
119INSERT_FILE_CON+="BIN_PATH=bin/\n"
120INSERT_FILE_CON+="INCLUDE_PATH=include/\n"
121INSERT_FILE_CON+="LIB_PATH=lib/\n"
122INSERT_FILE_CON+="MODULE_NAME = $1\n"
123INSERT_FILE_CON+="MODULE_FILE = \$(MODULE_NAME) \n"
124INSERT_FILE_CON+="MODULE_INC =\n\n\n\n"
125INSERT_FILE_CON+="MODULE_T = test_\$(MODULE_NAME)_main\n"
126INSERT_FILE_CON+="MODULE_TS = \$(SRC_PATH)\$(MODULE_T).c\n"
127INSERT_FILE_CON+="MODULE_TB = \$(BIN_PATH)\$(MODULE_T)\n"
128INSERT_FILE_CON+="MODULE_SUB =\n\n\n"
129INSERT_FILE_CON+="MODULE_SRC = \$(addsuffix .c,\$(addprefix \$(SRC_PATH),\$(MODULE_FILE)))\n"
130INSERT_FILE_CON+="MODULE_OBJ = \$(addsuffix .o,\$(addprefix \$(OBJ_PATH),\$(MODULE_FILE)))\n"
131INSERT_FILE_CON+="MODULE_INC += \$(addsuffix .h,\$(addprefix \$(INC_PATH),\$(MODULE_FILE)))\n"
132INSERT_FILE_CON+="MODULE_LIB = lib\$(MODULE_NAME).a\n"
133INSERT_FILE_CON+="MODULE_BIN = \$(BIN_PATH)\$(MODULE_LIB)\n"
134INSERT_FILE_CON+="MODULE_SUB_LIB = \$(foreach var,\$(MODULE_SUB),\$(var)/\$(BIN_PATH)lib\$(var).a)\n"
135INSERT_FILE_CON+="MODULE_SUB_INC =\n\n\n"
136INSERT_FILE_CON+="LIB_NAME =\n\n"
137INSERT_FILE_CON+="test:\n\n\n\n"
138INSERT_FILE_CON+="ifndef MODULE_DEP\n"
139INSERT_FILE_CON+="\$(error No Dependence)\n"
140INSERT_FILE_CON+="endif\n"
141INSERT_FILE_CON+="\$(foreach var,\$(MODULE_FILE),\$(eval \$(OBJ_PATH)\$(var).o:\$(SRC_PATH)\$(var).c  \$(INC_PATH)\$(var).h))\n\n"
142INSERT_FILE_CON+="RM = -rm -f\n\n"
143INSERT_FILE_CON+="test:all \$(MODULE_TB)\n\n"
144INSERT_FILE_CON+="\$(MODULE_TB):\$(MODULE_TS) \$(MODULE_BIN)\n"
145INSERT_FILE_CON+="ifeq (\$(strip \$(LIB_NAME)),)\n"
146INSERT_FILE_CON+="  gcc -O2 \$(MODULE_SUB_INC) -I\$(INCLUDE_PATH) -I\$(INC_PATH) \$^ -L\$(BIN_PATH) -L\$(LIB_PATH) -l\$(MODULE_NAME) -o \$@\n"
147INSERT_FILE_CON+="else\n"
148INSERT_FILE_CON+="  gcc -O2 \$(MODULE_SUB_INC) -I\$(INCLUDE_PATH) -I\$(INC_PATH) \$^ -L\$(BIN_PATH) -L\$(LIB_PATH) -l\$(MODULE_NAME) -l\$(LIB_NAME) -o \$@\n"
149INSERT_FILE_CON+="endif\n\n"
150INSERT_FILE_CON+="\$(MODULE_OBJ):\n"
151INSERT_FILE_CON+="  gcc  \$(MODULE_SUB_INC) -I\$(INCLUDE_PATH) -I\$(INC_PATH) -c \$<  -o \$@\n\n\n"
152INSERT_FILE_CON+="\$(MODULE_BIN):\$(MODULE_OBJ) \$(MODULE_SUB_LIB)\n"
153INSERT_FILE_CON+="  <a href="http://my.oschina.net/u/578052" class="referer" target="_blank">@echo</a>  module bin \$@\n"
154INSERT_FILE_CON+="  -ar -r \$@ \$(MODULE_OBJ)\n"
155INSERT_FILE_CON+="  -ar -x \$(MODULE_SUB_LIB)\n"
156INSERT_FILE_CON+="  -ar -q \$@ *.o\n"
157INSERT_FILE_CON+="  \$(RM) *.o\n"
158INSERT_FILE_CON+="  ranlib \$@\n\n"
159 
160     
161     
162     
163INSERT_FILE_CON+="all:\$(MODULE_BIN)\n\n"  
164INSERT_FILE_CON+="\$(MODULE_SUB_LIB):   \$(MODULE_SUB)\n\n"
165INSERT_FILE_CON+="clean: \$(MODULE_SUB) clean_self\n\n"
166INSERT_FILE_CON+="clean_self:\n"
167INSERT_FILE_CON+="  \$(RM) \$(MODULE_OBJ)\n"
168INSERT_FILE_CON+="  \$(RM) \$(MODULE_BIN)\n"
169INSERT_FILE_CON+="  \$(RM) \$(MODULE_TB)\n\n"
170INSERT_FILE_CON+="rebuild:clean module_dep all\n\n"
171INSERT_FILE_CON+="\$(MODULE_SUB):\n"
172INSERT_FILE_CON+="  <a href="http://my.oschina.net/u/578052" class="referer" target="_blank">@echo</a>  \"***************  todo Module SUB\" \$@  \"*****************\"\n"
173INSERT_FILE_CON+="  - \$(MAKE) -C \$@ \$(MAKECMDGOALS)\n\n\n"
174INSERT_FILE_CON+="#module_dep:\n"
175INSERT_FILE_CON+="# gcc \$(MODULE_SUB_INC) -I\$(INC_PATH) -MM \$(MODULE_SRC)    > \$(MODULE_NAME).d\n"
176INSERT_FILE_CON+="# sed -i '1 i\$(MODULE_NAME)_DEP = \$(MODULE_NAME)_DEP' \$(MODULE_NAME).d\n"
177INSERT_FILE_CON+="# sed -i '/.o:/ s,^,\$(OBJ_PATH),' \$(MODULE_NAME).d\n\n"
178INSERT_FILE_CON+=".PHONY: test all clean clean_self rebuild \$(MODULE_SUB) module_dep\n"
179}
180insert_file_tmp(){
181#$1 path/filename.ext
182#$2 filename
183#$3 ext mode
184    case $3 in
185    $C_FILE_SUFFIX)
186    get_c_init_context $1 $2
187    ;;
188    $H_FILE_SUFFIX)
189    get_h_init_context $1 $2
190    ;;
191    $TEST_FILE_SUFFIX)
192    get_test_init_context $4 $2
193    ;;
194    $MAKE_FILE_SUFFIX)
195    get_make_init_context $2
196    ;;
197    esac
198    sed  -i "a\\$INSERT_FILE_CON" $1
199     
200}
201create_Makefile(){
202#$1 makefile name
203    NEW_FILENAME="Makefile"
204    check_file_exist $NEW_FILENAME
205    echo > $NEW_FILENAME
206    if [ $? = $OVERWRITE_FILE ];then
207        echo > $NEW_FILENAME
208        insert_file_tmp $NEW_FILENAME $MODULE_NAME $MAKE_FILE_SUFFIX
209        echo create /$MODULE_PATH/$NEW_FILENAME files
210        return $CREATE_NEW_FILE
211    else
212        return $EXIST_FILE
213    fi 
214         
215}
216create_file_in_sub_dir(){
217     
218    if [ -d $1 ];then
219        if [ $3 = $TEST_FILE_SUFFIX ]; then
220        NEW_FILENAME=$1/test_$4_main.c
221        else
222        NEW_FILENAME=$1/$2$3
223        fi
224        check_file_exist $NEW_FILENAME
225        if [ $? = $OVERWRITE_FILE ];then
226            echo > $NEW_FILENAME
227            insert_file_tmp $NEW_FILENAME $2 $3 $4
228            echo create /$MODULE_PATH/$NEW_FILENAME files
229            return $CREATE_NEW_FILE
230        else
231            return $EXIST_FILE
232        fi
233    else
234        echo  /$MODULE_PATH/$1 is not directory, create_file not continue...
235        return $CREATE_NEW_FILE_ERROR
236        #not exit , continue done the other cmd
237    fi
238}
239MODULE_FILE=MODULE_FILE
240MODULE_SRC=""
241OBJ_PATH=OBJ_PATH
242SRC_PATH=SRC_PATH
243MODULE_NAME_DEP_CHECK="ifndef MODULE_DEP"
244RETURN_VALUE=
245 
246read_value_from_file(){
247#$1 filename $s2 valuename $3 is not add
248#get return ,need used RETURN_VALUE
249var=$2
250mode=
251 
252    unset RETURN_VALUE
253 
254    while read var;do
255         
256        case $var in
257        \#*)    ;;
258        \.*)    ;;
259        *)
260         
261        var=`echo $var | sed -n "/^$2[\ ]*=/p"`
262        #get name  += value
263        #name ?= value .....
264        if [ -z "$var" ]; then
265            continue;
266        fi
267        #echo step1 $var
268        mode=`echo $var | sed -n "/+=/p"`
269        var=`echo $var | sed -n "s/^.*=//p"`
270        if [ -z "$mode" ]; then
271            RETURN_VALUE=$var
272            continue;
273        else
274            if [ 3 -le $# ]; then
275            RETURN_VALUE=${RETURN_VALUE}${var}
276            fi
277        fi
278        #echo step2 $RETURN_VALUE
279 
280        esac
281    done < $1
282#   echo get return_value $RETURN_VALUE
283    return
284}
285get_first_data(){
286    echo first data $1
287    return $1
288}
289get_last_data(){
290    while [ 1 -lt $# ];do
291        shift
292    done
293    echo last1 data $1
294    return $1
295}
296cut_lines_in_file(){
297#cut from $2 line to $3 line in file $1
298#not check $1 file exist ,static func only
299first=
300last1=
301    #echo $2 $3
302    unset first
303    unset last1
304    first=`sed -n "/$2/=" $1`
305    last1=`sed -n "/$3/=" $1`
306    if [ -n "$first" -a -n "$last1" ]; then
307        get_first_data $first
308        first=$?
309        get_last_data $last1
310        last1=`expr $? - 1`
311        echo $first ${last1} $1
312        sed -i "${first},${last1}d" $1
313    fi
314    return
315      
316}
317get_sub_module(){
318    #$1 Makefile file name
319    if [ -e $MAKEFILE ];then
320        echo "read info form $MAKEFILE ..."
321    else
322        echo "Makefile(${MAKEFILE}) not exist!"
323        unset RETURN_VALUE
324        return
325    fi
326    read_value_from_file $1 "MODULE_SUB"
327#   echo $RETURN_VALUE
328    exit   
329}
330cut_value_from_const(){
331#$1 if have $(XXX) ,will cut
332    RETURN_VALUE=`echo $RETURN_VALUE | sed -n " s/[\$][(][^)]*[)]/ /p"`
333     
334}
335MODULE_INC=
336adjust_MODULE_INC(){
337    MODULE_INC=`echo $MODULE_INC|sed -n "s/[^ ]*/ -I&/gp"`
338}
339MODULE_SUB_ALL_PATH=
340get_inc_path(){
341path_tmp=
342    echo "all subdir is: " $@
343    while [ 1 -le $# ] ;do
344         
345        path_tmp=`echo $1 | sed -n "s/^.*$/ &\Makefile/p"`
346        echo "ready get file is :" $path_tmp
347        read_value_from_file $path_tmp "MODULE_SUB" "+"
348        MODULE_SUB1=$RETURN_VALUE
349         
350        if [ -z "$MODULE_SUB1" ]; then
351            MODULE_SUB_ALL_PATH+=${1}
352            echo "No MODULE_SUB more..." $1
353            shift
354            continue;
355        fi
356        MODULE_SUB1=`echo $MODULE_SUB1 | sed -e "/[^ ]*/s,,$1&\/,g"`
357        MODULE_SUB_ALL_PATH+=$1
358        get_inc_path $MODULE_SUB1
359        shift
360    done
361}
362get_all_INC_path(){
363    unset MODULE_SUB_ALL_PATH
364    get_inc_path "../$MODULE_NAME/"
365 
366    MODULE_SUB_ALL_PATH=`echo $MODULE_SUB_ALL_PATH | sed -n "/[\.][\.][]\/]/s,, &,gp"`
367    MODULE_SUB_ALL_PATH=`echo $MODULE_SUB_ALL_PATH | sed -n "/[\.][\.][]\/][^\.^ ]*/s,, -I&inc -I&include,gp"`
368    echo "all path is : " $MODULE_SUB_ALL_PATH
369    #exit  
370}
371create_depend_file(){
372#use gcc -MM create dependfile 
373#$1 module_name $2 makefile name not support!!
374    #if [ 2 -le $# ];then
375    #   MAKEFILE=$2
376    #else
377        MAKEFILE=Makefile
378    #fi
379     
380 
381    #get_sub_module $MAKEFILE
382#   echo $MAKEFILE set MAKEFILE default is Makefile
383    if [ -e $MAKEFILE ];then
384        echo "read info form $MAKEFILE ..."
385    else
386        echo "Makefile(${MAKEFILE}) not exist!"
387        exit
388    fi
389    read_value_from_file $MAKEFILE $SRC_PATH
390    SRC_PATH=$RETURN_VALUE
391    read_value_from_file $MAKEFILE $OBJ_PATH
392    OBJ_PATH=$RETURN_VALUE 
393    read_value_from_file $MAKEFILE $MODULE_FILE "+"
394    echo return_cut begin $RETURN_VALUE
395    cut_value_from_const $RETURN_VALUE
396    echo return_cut end $RETURN_VALUE
397    MODULE_FILE=${MODULE_NAME}" "${RETURN_VALUE} #insert space
398    MODULE_SRC=`echo $MODULE_FILE | sed -e "/[^ ]*/s,,$SRC_PATH&.c,g"`
399    echo "MODULE INFO:"
400    echo "SRC_PATH = "$SRC_PATH
401    echo "OBJ_PATH = "$SRC_PATH
402    echo "MODULE_FILE = "$MODULE_FILE
403    echo "MODULE_SRC = "$MODULE_SRC
404    get_all_INC_path
405    gcc $MODULE_SUB_ALL_PATH  -MM $MODULE_SRC > $MODULE_NAME.d
406    sed -i "1 iMODULE_DEP = ${MODULE_NAME}_DEP" $MODULE_NAME.d
407    sed -i "/.o:/ s,^,${OBJ_PATH}," $MODULE_NAME.d
408    cut_lines_in_file $MAKEFILE ${MODULE_NAME}_DEP  "$MODULE_NAME_DEP_CHECK"
409    echo "Dependinfo is :"
410    cat  $MODULE_NAME.d
411    echo "Dependinfo end"
412    sed -i "/ifndef[ ]*MODULE_DEP/i ifndef__TMP MODULE_DEP" $MAKEFILE
413 
414    sed -i "/ifndef__TMP[ ]*MODULE_DEP/r $MODULE_NAME.d" $MAKEFILE
415    sed -i "/ifndef__TMP[ ]*MODULE_DEP/d"  $MAKEFILE
416    sed -i "/^MODULE_SUB_INC.*$/s,,MODULE_SUB_INC = $MODULE_SUB_ALL_PATH," $MAKEFILE
417#check LIB_NAME
418         
419     
420    return
421 
422}
423 
424check_other_cmd(){
425#MODULE_INC="a b/c/d e"
426#   echo $MODULE_INC
427#   adjust_MODULE_INC
428#   echo $MODULE_INC
429#   exit
430    #MODULE_SUB= read_value_from_file "Makefile" "MODULE_SUB" "+"
431 
432    #echo $MODULE_SUB1
433    #exit
434 
435     
436while [ 2 -le $# ];do
437    case $2 in
438    $CREATE_FILE_FLAG)
439        shift
440        create_file_in_sub_dir $SRC_DIR_NAME $2 $C_FILE_SUFFIX #$C_FILE_TMP
441        create_file_in_sub_dir $INC_DIR_NAME $2 $H_FILE_SUFFIX #$H_FILE_TMP
442         
443        #create_file_in_sub_dir $LOG_DIR_NAME $2 $LOG_FILE_SUFFIX
444         
445    ;;
446    $CREATE_TEST_FILE_FLAG)
447        shift
448        create_file_in_sub_dir $SRC_DIR_NAME $2 $TEST_FILE_SUFFIX  $3
449        shift
450         
451        ;;
452    $CREATE_H_FILE_FLAG)
453        shift
454        create_file_in_sub_dir $INC_DIR_NAME $2 $H_FILE_SUFFIX #$H_FILE_TMP
455        ;; 
456    $CREATE_DEP_FILE)
457        #shift
458        create_depend_file $MODULE_NAME #$2
459        ;;
460    $CREATE_MAKEFILE_FILE)
461        #shift
462        create_Makefile $MODULE_NAME
463        ;;
464    *)
465        ;;
466       #    echo $2" test "
467    esac
468        shift
469done
470    exit
471}
472echo $MODULE_PATH
473 
474create_mkdir $MODULE_PATH
475is_created=$?
476echo $is_created
477 
478    MODULE_NAME=`echo $MODULE_PATH|sed -e "s/^.*[\/]//"`
479 
480if [ -d $MODULE_PATH ];then
481    cd $MODULE_PATH
482    create_mkdir $SRC_DIR_NAME
483    create_mkdir $INC_DIR_NAME
484    create_mkdir $BIN_DIR_NAME
485    create_mkdir $OBJ_DIR_NAME
486    create_mkdir $LIB_DIR_NAME
487    create_mkdir $INCLUDE_DIR_NAME     
488    if [ "$is_created" -eq "1" ];then
489    #create_Makefile $MODULE_NAME
490    check_other_cmd $@ -f $MODULE_NAME -t $MODULE_NAME $MODULE_NAME -m -d
491    else
492    check_other_cmd $@
493    fi
494else
495    echo $MODULE_NAME is not directory ,could not continue...  
496    exit
497fi

 

 

 

转载于:https://my.oschina.net/luckystar/blog/67090

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值