正题谈到模块化的设计方式。这里给出模块化Makefile模板的创建脚本的改良方案。先说说目标。然后贴上源码,最后给出一些简单的解释。如果有网友对特别是脚本的实现方法,有更好的方式,记得给个指正。我一向,“不怕被鄙视,就怕自认为一切OK。”
谈目标前,得再谈一下程序开发,或者软件设计。编写程序,最终形成客户需要的软件,需要经过很多步骤。去掉后面包装的事情,仅谈开发,也包括问题细化,原型验证,平台验证,整体优化四个阶段。不过阶段与阶段之间,不是因果关系,有时甚至是递归。
什么是问题细化。假设客户说,我要吃东西。于是乎,你随地捡起块石头放桌上。客户说,不行,第一,我要吃食物(靠不早说,只不过他以为你知道),第二刚拉过便便,我需要工具而不是用手。但至少现在明确了,需要个桌子,椅子,而且他已经就位了。
于是乎,你拖来一头猪,外加一把菜刀。客户说,不行,第一,猪是生的,(死活暂不谈),第二,菜刀给我也没有用。
于是乎,你切成块,该煮的还要煮,遇到色香味缺一的,还要回炉。
软件开发,准确说是客户需求实现,和其他很多服务类似,例如“个人艺术照”,无论是定制,还是产品化。只不过后者是先将客户一棒子敲晕,后收钱。前者是不停的按客户需求实现,等到客户没时间了,算了解。
因此,问题的细化,有时不单单是设计人员的问题,和客户本身也有关系。而原型验证,平台验证是由具体问题需求所产生的。而整体优化,这属于一个客户体验度 的问题。或者是问题本身。例如客户觉得原先的方案慢了。那么客户的基础目标已经全部确立,原先的方案就OK。只是体验度目标,客户要求调整。不过需要明 确,这两类的目标有很大差异。基础目标是客户的问题本身,体验度属于实现方案客户体验的问题。因此,后者是明确建立在前者基础之上的。
说了这么多,是希望将整体优化,和其他工作区别开来。优化属于客户满意度的问题。而模块化项目组织,只是解决客户的基础问题而不是体验度。但是模块化的项目组织好坏,直接影响后期整体优化的项目开展进度。
而对于开发者而言,还有一个和客户没有关系的问题,如何提高工作效率,降低重复性劳动。在面向对象问题上,采用类复用的技术,而在C语言开发中,模块化的方式,则更为有效。采用模块化开发至少有以下几个优势:
1、问题分而治之。有效降低局部问题的扩散性的情况。
2、复用技术,可以将设计工作重点集中在目标的特性上。
3、对系统的理解更为容易,便于后期客户目标调整时的方案调整。
针对上述好处,由此确定出模块化Makefile创建模板的目标。需要达到以下几个要求。
1、每个目录组成一个模块。当然包括这个目录下的子模块。
2、模块模板创建脚本能自动生成模块,包括目录,模块接口C文件,对应头文件,对应测试文件。对应当前默认Makefile。
3、对应Makefile可以具备递归处理所依赖的子模块的make工作。
由此我修正了前面的create_module.sh 的脚本。如下。
014 |
CREATE_H_FILE_FLAG=-h |
015 |
CREATE_TEST_FILE_FLAG=-t |
016 |
CREATE_MAKEFILE_FILE=-m |
022 |
mkdir $1 > /dev/null 2>&1 |
031 |
echo "could not create directory " /$1 |
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 |
045 |
return $OVERWRITE_FILE |
049 |
return $NOT_OVERWRITE_FILE |
055 |
echo "fuck ,i need you correct answer!" |
059 |
return $OVERWRITE_FILE |
063 |
CREATE_NEW_FILE_ERROR=1 |
067 |
get_c_init_context(){ |
068 |
#$1 path/filename.ext |
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 |
085 |
get_h_init_context(){ |
086 |
#$1 path/filename.ext |
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" |
096 |
get_test_init_context(){ |
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" |
110 |
get_make_init_context(){ |
112 |
INSERT_FILE_CON= "SRC_PATH=src/\n" |
113 |
INSERT_FILE_CON+= "INC_PATH=inc/\n" |
114 |
INSERT_FILE_CON+= "OBJ_PATH=obj/\n" |
115 |
INSERT_FILE_CON+= "BIN_PATH=bin/\n" |
116 |
INSERT_FILE_CON+= "MODULE_NAME = $1\n" |
117 |
INSERT_FILE_CON+= "MODULE_FILE = \$(MODULE_NAME) \n" |
118 |
INSERT_FILE_CON+= "MODULE_INC =\n\n\n\n" |
119 |
INSERT_FILE_CON+= "MODULE_T = test_\$(MODULE_NAME)_main\n" |
120 |
INSERT_FILE_CON+= "MODULE_TS = \$(SRC_PATH)\$(MODULE_T).c\n" |
121 |
INSERT_FILE_CON+= "MODULE_TB = \$(BIN_PATH)\$(MODULE_T)\n" |
122 |
INSERT_FILE_CON+= "MODULE_SUB =\n\n\n" |
123 |
INSERT_FILE_CON+= "MODULE_SRC = \$(addsuffix .c,\$(addprefix \$(SRC_PATH),\$(MODULE_FILE)))\n" |
124 |
INSERT_FILE_CON+= "MODULE_OBJ = \$(addsuffix .o,\$(addprefix \$(OBJ_PATH),\$(MODULE_FILE)))\n" |
125 |
INSERT_FILE_CON+= "MODULE_INC += \$(addsuffix .h,\$(addprefix \$(INC_PATH),\$(MODULE_FILE)))\n" |
126 |
INSERT_FILE_CON+= "MODULE_LIB = lib\$(MODULE_NAME).a\n" |
127 |
INSERT_FILE_CON+= "MODULE_BIN = \$(BIN_PATH)\$(MODULE_LIB)\n" |
128 |
INSERT_FILE_CON+= "MODULE_SUB_LIB = \$(foreach var,\$(MODULE_SUB),\$(var)/\$(BIN_PATH)lib\$(var).a)\n" |
129 |
INSERT_FILE_CON+= "MODULE_SUB_INC =\n\n\n" |
130 |
INSERT_FILE_CON+= "test:\n\n\n\n" |
131 |
INSERT_FILE_CON+= "ifndef MODULE_DEP\n" |
132 |
INSERT_FILE_CON+= "\$(error No Dependence)\n" |
133 |
INSERT_FILE_CON+= "endif\n" |
134 |
INSERT_FILE_CON+= "\$(foreach var,\$(MODULE_FILE),\$(eval \$(OBJ_PATH)\$(var).o:\$(SRC_PATH)\$(var).c \$(INC_PATH)\$(var).h))\n\n" |
135 |
INSERT_FILE_CON+= "RM = -rm -f\n\n" |
136 |
INSERT_FILE_CON+= "test:all \$(MODULE_TB)\n\n" |
137 |
INSERT_FILE_CON+= "\$(MODULE_TB):\$(MODULE_TS)\n" |
138 |
INSERT_FILE_CON+= " gcc -O2 -I\$(MODULE_SUB_INC) -I\$(INC_PATH) \$^ -L\$(BIN_PATH) -l\$(MODULE_NAME) -o \$@\n\n\n" |
139 |
INSERT_FILE_CON+= "\$(MODULE_OBJ):\n" |
140 |
INSERT_FILE_CON+= " gcc -I\$(MODULE_SUB_INC) -I\$(INC_PATH) -c \$< -o \$@\n\n\n" |
141 |
INSERT_FILE_CON+= "\$(MODULE_BIN):\$(MODULE_OBJ) \$(MODULE_SUB_LIB)\n" |
142 |
INSERT_FILE_CON+= " <a href=" http://my.oschina.net/yuning0502 " target=" _blank " rel=" nofollow ">@echo</a> module bin \$@\n" |
143 |
INSERT_FILE_CON+= " ar -r \$@ \$(MODULE_OBJ)\n" |
144 |
INSERT_FILE_CON+= " ar -q \$@ \$(MODULE_SUB_LIB)\n\n" |
145 |
INSERT_FILE_CON+= "all:\$(MODULE_BIN)\n\n" |
146 |
INSERT_FILE_CON+= "\$(MODULE_SUB_LIB): \$(MODULE_SUB)\n\n" |
147 |
INSERT_FILE_CON+= "clean: \$(MODULE_SUB) clean_self\n\n" |
148 |
INSERT_FILE_CON+= "clean_self:\n" |
149 |
INSERT_FILE_CON+= " \$(RM) \$(MODULE_OBJ)\n" |
150 |
INSERT_FILE_CON+= " \$(RM) \$(MODULE_BIN)\n" |
151 |
INSERT_FILE_CON+= " \$(RM) \$(MODULE_TB)\n\n" |
152 |
INSERT_FILE_CON+= "rebuild:clean module_dep all\n\n" |
153 |
INSERT_FILE_CON+= "\$(MODULE_SUB):\n" |
154 |
INSERT_FILE_CON+= " <a href=" http://my.oschina.net/yuning0502 " target=" _blank " rel=" nofollow ">@echo</a> \"*************** todo Module SUB\" \$@ \"*****************\"\n" |
155 |
INSERT_FILE_CON+= " - \$(MAKE) -C \$@ \$(MAKECMDGOALS)\n\n\n" |
156 |
INSERT_FILE_CON+= "#module_dep:\n" |
157 |
INSERT_FILE_CON+= "# gcc -I\$(MODULE_SUB_INC) -I\$(INC_PATH) -MM \$(MODULE_SRC) > \$(MODULE_NAME).d\n" |
158 |
INSERT_FILE_CON+= "# sed -i '1 i\$(MODULE_NAME)_DEP = \$(MODULE_NAME)_DEP' \$(MODULE_NAME).d\n" |
159 |
INSERT_FILE_CON+= "# sed -i '/.o:/ s,^,\$(OBJ_PATH),' \$(MODULE_NAME).d\n\n" |
160 |
INSERT_FILE_CON+= ".PHONY: test all clean clean_self rebuild \$(MODULE_SUB) module_dep\n" |
163 |
#$1 path/filename.ext |
168 |
get_c_init_context $1 $2 |
171 |
get_h_init_context $1 $2 |
174 |
get_test_init_context $4 $2 |
177 |
get_make_init_context $2 |
180 |
sed -i "a\\$INSERT_FILE_CON" $1 |
185 |
NEW_FILENAME= "Makefile" |
186 |
check_file_exist $NEW_FILENAME |
188 |
if [ $? = $OVERWRITE_FILE ]; then |
190 |
insert_file_tmp $NEW_FILENAME $MODULE_NAME $MAKE_FILE_SUFFIX |
191 |
echo create /$MODULE_PATH/$NEW_FILENAME files |
192 |
return $CREATE_NEW_FILE |
198 |
create_file_in_sub_dir(){ |
201 |
if [ $3 = $TEST_FILE_SUFFIX ]; then |
202 |
NEW_FILENAME=$1/test_$4_main.c |
206 |
check_file_exist $NEW_FILENAME |
207 |
if [ $? = $OVERWRITE_FILE ]; then |
209 |
insert_file_tmp $NEW_FILENAME $2 $3 $4 |
210 |
echo create /$MODULE_PATH/$NEW_FILENAME files |
211 |
return $CREATE_NEW_FILE |
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 |
221 |
MODULE_FILE=MODULE_FILE |
225 |
MODULE_NAME_DEP_CHECK= "ifndef MODULE_DEP" |
228 |
read_value_from_file(){ |
229 |
#$1 filename $s2 valuename $3 is not add |
230 |
#get return ,need used RETURN_VALUE |
243 |
var=` echo $var | sed -n "/^$2[\ ]*=/p" ` |
246 |
if [ -z "$var" ]; then |
250 |
mode=` echo $var | sed -n "/+=/p" ` |
251 |
var=` echo $var | sed -n "s/^.*=//p" ` |
252 |
if [ -z "$mode" ]; then |
256 |
if [ 3 - le $ # ]; then |
257 |
RETURN_VALUE=${RETURN_VALUE}${var} |
260 |
#echo step2 $RETURN_VALUE |
264 |
# echo get return_value $RETURN_VALUE |
272 |
while [ 1 - lt $ # ];do |
279 |
#cut from $2 line to $3 line in file $1 |
280 |
#not check $1 file exist ,static func only |
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 |
293 |
echo $first ${last1} $1 |
294 |
sed -i "${first},${last1}d" $1 |
300 |
#$1 Makefile file name |
301 |
if [ -e $MAKEFILE ]; then |
302 |
echo "read info form $MAKEFILE ..." |
304 |
echo "Makefile(${MAKEFILE}) not exist!" |
308 |
read_value_from_file $1 "MODULE_SUB" |
312 |
cut_value_from_const(){ |
313 |
#$1 if have $(XXX) ,will cut |
314 |
RETURN_VALUE=` echo $RETURN_VALUE | sed -n "s/[\$][(][^)]*[)]/ /p" ` |
319 |
MODULE_INC=` echo $MODULE_INC| sed -n "s/[^ ]*/ -I&/gp" ` |
324 |
echo "all subdir is: " $@ |
325 |
while [ 1 - le $ # ] ;do |
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 |
332 |
if [ -z "$MODULE_SUB1" ]; then |
333 |
MODULE_SUB_ALL_PATH+=${1} |
334 |
echo "No MODULE_SUB more..." $1 |
338 |
MODULE_SUB1=` echo $MODULE_SUB1 | sed -e "/[^ ]*/s,,$1&\/,g" ` |
339 |
MODULE_SUB_ALL_PATH+=$1 |
340 |
get_inc_path $MODULE_SUB1 |
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 |
352 |
create_depend_file(){ |
353 |
#use gcc -MM create dependfile |
354 |
#$1 module_name $2 makefile name not support!! |
355 |
#if [ 2 -le $# ];then |
362 |
#get_sub_module $MAKEFILE |
363 |
# echo $MAKEFILE set MAKEFILE default is Makefile |
364 |
if [ -e $MAKEFILE ]; then |
365 |
echo "read info form $MAKEFILE ..." |
367 |
echo "Makefile(${MAKEFILE}) not exist!" |
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" ` |
381 |
echo "SRC_PATH = " $SRC_PATH |
382 |
echo "OBJ_PATH = " $SRC_PATH |
383 |
echo "MODULE_FILE = " $MODULE_FILE |
384 |
echo "MODULE_SRC = " $MODULE_SRC |
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 :" |
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 |
402 |
#MODULE_INC="a b/c/d e" |
407 |
#MODULE_SUB= read_value_from_file "Makefile" "MODULE_SUB" "+" |
413 |
while [ 2 - le $ # ];do |
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 |
420 |
#create_file_in_sub_dir $LOG_DIR_NAME $2 $LOG_FILE_SUFFIX |
423 |
$CREATE_TEST_FILE_FLAG) |
425 |
create_file_in_sub_dir $SRC_DIR_NAME $2 $TEST_FILE_SUFFIX $3 |
431 |
create_file_in_sub_dir $INC_DIR_NAME $2 $H_FILE_SUFFIX #$H_FILE_TMP |
435 |
create_depend_file $MODULE_NAME #$2 |
437 |
$CREATE_MAKEFILE_FILE) |
439 |
create_Makefile $MODULE_NAME |
451 |
create_mkdir $MODULE_PATH |
455 |
MODULE_NAME=` echo $MODULE_PATH| sed -e "s/^.*[\/]//" ` |
457 |
if [ -d $MODULE_PATH ]; then |
459 |
create_mkdir $SRC_DIR_NAME |
460 |
create_mkdir $INC_DIR_NAME |
461 |
create_mkdir $BIN_DIR_NAME |
462 |
create_mkdir $OBJ_DIR_NAME |
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 |
471 |
echo $MODULE_NAME is not directory ,could not continue ... |
需要解释一下修正的几个部分。
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
009 |
INCLUDE_DIR_NAME=include |
016 |
CREATE_H_FILE_FLAG=-h |
017 |
CREATE_TEST_FILE_FLAG=-t |
018 |
CREATE_MAKEFILE_FILE=-m |
024 |
mkdir $1 > /dev/null 2>&1 |
033 |
echo "could not create directory " /$1 |
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 |
047 |
return $OVERWRITE_FILE |
051 |
return $NOT_OVERWRITE_FILE |
057 |
echo "fuck ,i need you correct answer!" |
061 |
return $OVERWRITE_FILE |
065 |
CREATE_NEW_FILE_ERROR=1 |
069 |
get_c_init_context(){ |
070 |
#$1 path/filename.ext |
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 |
087 |
get_h_init_context(){ |
088 |
#$1 path/filename.ext |
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" |
100 |
get_test_init_context(){ |
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" |
114 |
get_make_init_context(){ |
116 |
INSERT_FILE_CON= "SRC_PATH=src/\n" |
117 |
INSERT_FILE_CON+= "INC_PATH=inc/\n" |
118 |
INSERT_FILE_CON+= "OBJ_PATH=obj/\n" |
119 |
INSERT_FILE_CON+= "BIN_PATH=bin/\n" |
120 |
INSERT_FILE_CON+= "INCLUDE_PATH=include/\n" |
121 |
INSERT_FILE_CON+= "LIB_PATH=lib/\n" |
122 |
INSERT_FILE_CON+= "MODULE_NAME = $1\n" |
123 |
INSERT_FILE_CON+= "MODULE_FILE = \$(MODULE_NAME) \n" |
124 |
INSERT_FILE_CON+= "MODULE_INC =\n\n\n\n" |
125 |
INSERT_FILE_CON+= "MODULE_T = test_\$(MODULE_NAME)_main\n" |
126 |
INSERT_FILE_CON+= "MODULE_TS = \$(SRC_PATH)\$(MODULE_T).c\n" |
127 |
INSERT_FILE_CON+= "MODULE_TB = \$(BIN_PATH)\$(MODULE_T)\n" |
128 |
INSERT_FILE_CON+= "MODULE_SUB =\n\n\n" |
129 |
INSERT_FILE_CON+= "MODULE_SRC = \$(addsuffix .c,\$(addprefix \$(SRC_PATH),\$(MODULE_FILE)))\n" |
130 |
INSERT_FILE_CON+= "MODULE_OBJ = \$(addsuffix .o,\$(addprefix \$(OBJ_PATH),\$(MODULE_FILE)))\n" |
131 |
INSERT_FILE_CON+= "MODULE_INC += \$(addsuffix .h,\$(addprefix \$(INC_PATH),\$(MODULE_FILE)))\n" |
132 |
INSERT_FILE_CON+= "MODULE_LIB = lib\$(MODULE_NAME).a\n" |
133 |
INSERT_FILE_CON+= "MODULE_BIN = \$(BIN_PATH)\$(MODULE_LIB)\n" |
134 |
INSERT_FILE_CON+= "MODULE_SUB_LIB = \$(foreach var,\$(MODULE_SUB),\$(var)/\$(BIN_PATH)lib\$(var).a)\n" |
135 |
INSERT_FILE_CON+= "MODULE_SUB_INC =\n\n\n" |
136 |
INSERT_FILE_CON+= "LIB_NAME =\n\n" |
137 |
INSERT_FILE_CON+= "test:\n\n\n\n" |
138 |
INSERT_FILE_CON+= "ifndef MODULE_DEP\n" |
139 |
INSERT_FILE_CON+= "\$(error No Dependence)\n" |
140 |
INSERT_FILE_CON+= "endif\n" |
141 |
INSERT_FILE_CON+= "\$(foreach var,\$(MODULE_FILE),\$(eval \$(OBJ_PATH)\$(var).o:\$(SRC_PATH)\$(var).c \$(INC_PATH)\$(var).h))\n\n" |
142 |
INSERT_FILE_CON+= "RM = -rm -f\n\n" |
143 |
INSERT_FILE_CON+= "test:all \$(MODULE_TB)\n\n" |
144 |
INSERT_FILE_CON+= "\$(MODULE_TB):\$(MODULE_TS) \$(MODULE_BIN)\n" |
145 |
INSERT_FILE_CON+= "ifeq (\$(strip \$(LIB_NAME)),)\n" |
146 |
INSERT_FILE_CON+= " gcc -O2 \$(MODULE_SUB_INC) -I\$(INCLUDE_PATH) -I\$(INC_PATH) \$^ -L\$(BIN_PATH) -L\$(LIB_PATH) -l\$(MODULE_NAME) -o \$@\n" |
147 |
INSERT_FILE_CON+= "else\n" |
148 |
INSERT_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" |
149 |
INSERT_FILE_CON+= "endif\n\n" |
150 |
INSERT_FILE_CON+= "\$(MODULE_OBJ):\n" |
151 |
INSERT_FILE_CON+= " gcc \$(MODULE_SUB_INC) -I\$(INCLUDE_PATH) -I\$(INC_PATH) -c \$< -o \$@\n\n\n" |
152 |
INSERT_FILE_CON+= "\$(MODULE_BIN):\$(MODULE_OBJ) \$(MODULE_SUB_LIB)\n" |
153 |
INSERT_FILE_CON+= " <a href=" http://my.oschina.net/u/578052 " class=" referer " target=" _blank ">@echo</a> module bin \$@\n" |
154 |
INSERT_FILE_CON+= " -ar -r \$@ \$(MODULE_OBJ)\n" |
155 |
INSERT_FILE_CON+= " -ar -x \$(MODULE_SUB_LIB)\n" |
156 |
INSERT_FILE_CON+= " -ar -q \$@ *.o\n" |
157 |
INSERT_FILE_CON+= " \$(RM) *.o\n" |
158 |
INSERT_FILE_CON+= " ranlib \$@\n\n" |
163 |
INSERT_FILE_CON+= "all:\$(MODULE_BIN)\n\n" |
164 |
INSERT_FILE_CON+= "\$(MODULE_SUB_LIB): \$(MODULE_SUB)\n\n" |
165 |
INSERT_FILE_CON+= "clean: \$(MODULE_SUB) clean_self\n\n" |
166 |
INSERT_FILE_CON+= "clean_self:\n" |
167 |
INSERT_FILE_CON+= " \$(RM) \$(MODULE_OBJ)\n" |
168 |
INSERT_FILE_CON+= " \$(RM) \$(MODULE_BIN)\n" |
169 |
INSERT_FILE_CON+= " \$(RM) \$(MODULE_TB)\n\n" |
170 |
INSERT_FILE_CON+= "rebuild:clean module_dep all\n\n" |
171 |
INSERT_FILE_CON+= "\$(MODULE_SUB):\n" |
172 |
INSERT_FILE_CON+= " <a href=" http://my.oschina.net/u/578052 " class=" referer " target=" _blank ">@echo</a> \"*************** todo Module SUB\" \$@ \"*****************\"\n" |
173 |
INSERT_FILE_CON+= " - \$(MAKE) -C \$@ \$(MAKECMDGOALS)\n\n\n" |
174 |
INSERT_FILE_CON+= "#module_dep:\n" |
175 |
INSERT_FILE_CON+= "# gcc \$(MODULE_SUB_INC) -I\$(INC_PATH) -MM \$(MODULE_SRC) > \$(MODULE_NAME).d\n" |
176 |
INSERT_FILE_CON+= "# sed -i '1 i\$(MODULE_NAME)_DEP = \$(MODULE_NAME)_DEP' \$(MODULE_NAME).d\n" |
177 |
INSERT_FILE_CON+= "# sed -i '/.o:/ s,^,\$(OBJ_PATH),' \$(MODULE_NAME).d\n\n" |
178 |
INSERT_FILE_CON+= ".PHONY: test all clean clean_self rebuild \$(MODULE_SUB) module_dep\n" |
181 |
#$1 path/filename.ext |
186 |
get_c_init_context $1 $2 |
189 |
get_h_init_context $1 $2 |
192 |
get_test_init_context $4 $2 |
195 |
get_make_init_context $2 |
198 |
sed -i "a\\$INSERT_FILE_CON" $1 |
203 |
NEW_FILENAME= "Makefile" |
204 |
check_file_exist $NEW_FILENAME |
206 |
if [ $? = $OVERWRITE_FILE ]; then |
208 |
insert_file_tmp $NEW_FILENAME $MODULE_NAME $MAKE_FILE_SUFFIX |
209 |
echo create /$MODULE_PATH/$NEW_FILENAME files |
210 |
return $CREATE_NEW_FILE |
216 |
create_file_in_sub_dir(){ |
219 |
if [ $3 = $TEST_FILE_SUFFIX ]; then |
220 |
NEW_FILENAME=$1/test_$4_main.c |
224 |
check_file_exist $NEW_FILENAME |
225 |
if [ $? = $OVERWRITE_FILE ]; then |
227 |
insert_file_tmp $NEW_FILENAME $2 $3 $4 |
228 |
echo create /$MODULE_PATH/$NEW_FILENAME files |
229 |
return $CREATE_NEW_FILE |
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 |
239 |
MODULE_FILE=MODULE_FILE |
243 |
MODULE_NAME_DEP_CHECK= "ifndef MODULE_DEP" |
246 |
read_value_from_file(){ |
247 |
#$1 filename $s2 valuename $3 is not add |
248 |
#get return ,need used RETURN_VALUE |
261 |
var=` echo $var | sed -n "/^$2[\ ]*=/p" ` |
264 |
if [ -z "$var" ]; then |
268 |
mode=` echo $var | sed -n "/+=/p" ` |
269 |
var=` echo $var | sed -n "s/^.*=//p" ` |
270 |
if [ -z "$mode" ]; then |
274 |
if [ 3 - le $ # ]; then |
275 |
RETURN_VALUE=${RETURN_VALUE}${var} |
278 |
#echo step2 $RETURN_VALUE |
282 |
# echo get return_value $RETURN_VALUE |
290 |
while [ 1 - lt $ # ];do |
297 |
#cut from $2 line to $3 line in file $1 |
298 |
#not check $1 file exist ,static func only |
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 |
311 |
echo $first ${last1} $1 |
312 |
sed -i "${first},${last1}d" $1 |
318 |
#$1 Makefile file name |
319 |
if [ -e $MAKEFILE ]; then |
320 |
echo "read info form $MAKEFILE ..." |
322 |
echo "Makefile(${MAKEFILE}) not exist!" |
326 |
read_value_from_file $1 "MODULE_SUB" |
330 |
cut_value_from_const(){ |
331 |
#$1 if have $(XXX) ,will cut |
332 |
RETURN_VALUE=` echo $RETURN_VALUE | sed -n " s/[\$][(][^)]*[)]/ /p" ` |
337 |
MODULE_INC=` echo $MODULE_INC| sed -n "s/[^ ]*/ -I&/gp" ` |
342 |
echo "all subdir is: " $@ |
343 |
while [ 1 - le $ # ] ;do |
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 |
350 |
if [ -z "$MODULE_SUB1" ]; then |
351 |
MODULE_SUB_ALL_PATH+=${1} |
352 |
echo "No MODULE_SUB more..." $1 |
356 |
MODULE_SUB1=` echo $MODULE_SUB1 | sed -e "/[^ ]*/s,,$1&\/,g" ` |
357 |
MODULE_SUB_ALL_PATH+=$1 |
358 |
get_inc_path $MODULE_SUB1 |
363 |
unset MODULE_SUB_ALL_PATH |
364 |
get_inc_path "../$MODULE_NAME/" |
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 |
371 |
create_depend_file(){ |
372 |
#use gcc -MM create dependfile |
373 |
#$1 module_name $2 makefile name not support!! |
374 |
#if [ 2 -le $# ];then |
381 |
#get_sub_module $MAKEFILE |
382 |
# echo $MAKEFILE set MAKEFILE default is Makefile |
383 |
if [ -e $MAKEFILE ]; then |
384 |
echo "read info form $MAKEFILE ..." |
386 |
echo "Makefile(${MAKEFILE}) not exist!" |
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" ` |
400 |
echo "SRC_PATH = " $SRC_PATH |
401 |
echo "OBJ_PATH = " $SRC_PATH |
402 |
echo "MODULE_FILE = " $MODULE_FILE |
403 |
echo "MODULE_SRC = " $MODULE_SRC |
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 :" |
411 |
echo "Dependinfo end" |
412 |
sed -i "/ifndef[ ]*MODULE_DEP/i ifndef__TMP MODULE_DEP" $MAKEFILE |
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 |
425 |
#MODULE_INC="a b/c/d e" |
430 |
#MODULE_SUB= read_value_from_file "Makefile" "MODULE_SUB" "+" |
436 |
while [ 2 - le $ # ];do |
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 |
443 |
#create_file_in_sub_dir $LOG_DIR_NAME $2 $LOG_FILE_SUFFIX |
446 |
$CREATE_TEST_FILE_FLAG) |
448 |
create_file_in_sub_dir $SRC_DIR_NAME $2 $TEST_FILE_SUFFIX $3 |
454 |
create_file_in_sub_dir $INC_DIR_NAME $2 $H_FILE_SUFFIX #$H_FILE_TMP |
458 |
create_depend_file $MODULE_NAME #$2 |
460 |
$CREATE_MAKEFILE_FILE) |
462 |
create_Makefile $MODULE_NAME |
474 |
create_mkdir $MODULE_PATH |
478 |
MODULE_NAME=` echo $MODULE_PATH| sed -e "s/^.*[\/]//" ` |
480 |
if [ -d $MODULE_PATH ]; then |
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 |
495 |
echo $MODULE_NAME is not directory ,could not continue ... |