Makefile和shell脚本简单编写

时间:2022-01-04 09:25:01
#1、以下是海思3518E的ONVIF代码中简单的makefile分析
 
  
  1. CROSS =/opt/hisi-linux-nptl/arm-hisiv100-linux/bin/arm-hisiv100-linux-uclibcgnueabi-
  2. #CROSS =
  3. SRCDIRS = ./ \
  4. ./include\
  5. ./src\
  6. ./gsoap\
  7. ASFLAGS =
  8. CFLAGS = -Wall
  9. CXXFLAGS = -O2
  10. LDFLAGS =
  11. ARFLAGS =
  12. OCFLAGS =
  13. ODFLAGS =
  14. INCDIRS = -I../include -I../fcCommon -I./gsoap
  15. LIBDIRS = -L../../../lib/ ../../../lib/libfcMsgClient.a ../../../lib/libfcCommon.a ../../../lib/common/libssl.so.1.0.0 ../../../lib/common/libcrypto.so.1.0.0
  16. LIBS = -lpthread -lm
  17. #
  18. ### You shouldn't need to change anything below this point.
  19. #
  20. ##
  21. #AS = $(CROSS)as
  22. CC = $(CROSS)gcc
  23. CXX = $(CROSS)g++
  24. LD = $(CROSS)gcc
  25. AR = $(CROSS)ar
  26. OC = $(CROSS)objcopy
  27. OD = $(CROSS)objdump
  28. ST = $(CROSS)strip
  29. RM = -rm -fr
  30. #notdir 会取出当前目录的目录名
  31. NAME := $(notdir $(CURDIR))
  32. #foreach 递归取出所有的文件
  33. SFILES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.s))
  34. CFILES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c))
  35. CPPFILES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.cpp))
  36. RMFILES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*~))
  37. RMFILEO := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.o))
  38. #$(SFILES:.s=.o) 将所有的.s文件转换成.o文件
  39. OBJS := $(SFILES:.s=.o) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
  40. DEPS := $(OBJS:.o=.d)
  41. VPATH := $(SRCDIRS)
  42. #建一个虚拟的目标
  43. .PHONY: all rebuild clean
  44. all:
  45. @$(MAKE) $(NAME)
  46. rebuild:
  47. @$(MAKE) clean
  48. @$(MAKE) $(NAME)
  49. $(NAME): $(OBJS)
  50. @echo test linking ...
  51. # $(LD) $(LDFLAGS) $(LIBDIRS) -o $@ $^ $(LIBS)
  52. # $(LD) $(LDFLAGS) -o $@ $^ $(LIBS) $(LIBDIRS)
  53. $(CXX) $(LDFLAGS) -o fcOnvif -DWITH_PURE_VIRTUAL $^ $(LIBS) $(LIBDIRS)
  54. $(ST) -g --strip-unneeded fcOnvif
  55. cp fcOnvif /mnt/nfs
  56. # cp armok /tftpboot/
  57. #把当前所有依赖的.s文件编译成.o文件
  58. %.o: %.s
  59. @echo assembling $< ...
  60. $(AS) $(ASFLAGS) $(INCDIRS) $< -o $@
  61. %.o: %.c
  62. @echo test compiling $< ...
  63. $(CC) $(CFLAGS) $(INCDIRS) -c $< -o $@
  64. %.o: %.cpp
  65. @echo compiling $< ...
  66. $(CXX) -DWITH_PURE_VIRTUAL $(CXXFLAGS) $(INCDIRS) -c $< -o $@
  67. %.d: %.c
  68. @$(CC) $(CFLAGS) $(INCDIRS) -MM $^ -o $@.tmp
  69. @sed 's,$(basename $(notdir $@)).o[ :]*,$(@:.d=.o) $@ : ,g' $@.tmp > $@
  70. @$(RM) $@.tmp
  71. %.d: %.cpp
  72. @$(CXX) $(CXXFLAGS) $(INCDIRS) -MM $^ -o $@.tmp
  73. @sed 's,$(basename $(notdir $@)).o[ :]*,$(@:.d=.o) $@ : ,g' $@.tmp > $@
  74. @$(RM) $@.tmp
  75. ifeq (mach/mach,)
  76. -include $(DEPS)
  77. endif
  78. clean:
  79. @$(RM) $(OBJS) $(DEPS) $(NAME) $(RMFILES) $(RMFILEO)
  80. @echo clean completed
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。
1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符
 
  
  1. 例子:
  2. 建立一个测试目录,在测试目录下建立一个名为sub的子目录
  3. $ mkdir test
  4. $ cd test
  5. $ mkdir sub
  6. test下,建立a.cb.c2个文件,在sub目录下,建立sa.csb.c2 个文件
  7. 建立一个简单的Makefile
  8. src=$(wildcard *.c ./sub/*.c)
  9. dir=$(notdir $(src))
  10. obj=$(patsubst %.c,%.o,$(dir) )
  11. all:
  12. @echo $(src)
  13. @echo $(dir)
  14. @echo $(obj)
  15. @echo "end"
  16. 执行结果分析:
  17. 第一行输出:
  18. a.c b.c ./sub/sa.c ./sub/sb.c
  19. wildcard 指定目录 ./ ./sub/ 下的所有后缀是c的文件全部展开。
  20. 第二行输出:
  21. a.c b.c sa.c sb.c
  22. notdir把展开的文件去除掉路径信息
  23. 第三行输出:
  24. a.o b.o sa.o sb.o
自动化变量$?代表依赖文件列表中被改变过的所有文件。
自动化变量$^代表所有通过目录搜索得到的依赖文件的完整路径名(目录 + 一般文件名)列表。
自动化变量$@代表规则的目标。
自动化变量$<代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件。
自动化变量$(@D) 
The directory part of the file name of the target, 
with the trailing slash removed. If the value of ‘$@’ is dir/foo.o 
then ‘$(@D)’ is dir. This value is . if ‘$@’ does not contain a slash.
(目标文件名的目录部分,
并删除尾部斜杠。 如果'$ @'的值是dir / foo.o
那么'$(@ D)'是dir。 此值为。 如果'$ @'不包含斜杠。)
自动化变量$(@F)
The file-within-directory part of the file name of 
the target. If the value of ‘$@’ is dir/foo.o then ‘$(@F)’ is foo.o. 
‘$(@F)’ is equivalent to ‘$(notdir $@)’.
(文件内目录部分的文件名为目标。 如果'$ @'的值是dir / foo.o,那么'$(@ F)'是foo.o。
'$(@ F)'相当于'$(notdir $ @)'。) 
来源: http://blog.chinaunix.net/uid-20564848-id-217918.html
Linux shell 下循环读取文件test.txt的方式。(3种)
 
    
  1. #!/bin/bash
  2. printf "*************************************\n"
  3. echo " cat file whiel read line"
  4. cat test.txt |while read line
  5. do
  6. echo $line;
  7. done
  8. printf "*************************************\n"
  9. echo "while read line <file"
  10. while read line
  11. do
  12. echo $line;
  13. done <test.txt
  14. printf "*************************************\n"
  15. echo "for line in cat test.txt"
  16. SAVEIFS=$IFS
  17. IFS=$(echo -en "\n")
  18. for line in $(cat test.txt)
  19. do
  20. echo $line;
  21. done
  22. IFS=$SAVEIFS  
  23. 注意:for line in $(cat test.txt)   当文件中有空格或者tab 时,一定要设置一下IFS变量。