尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

makefile使用常见问题

makefile使用常见问题 makefile使用常见问题这个不是一个基础的makefile教程是使用过程中细节记录和总结。在类Unix系统中当我们使用源码编译某个软件的时候我们会使用confiure,make,make install这三个命令cofigure生成makefile文件make和make install编译和安装make工具下载下载gnumake 源码 采用GCC 编译执行目录 build_w32.bat gcc会编译生成make.exe gnumake.exe, 加入环境变量wildcard用来明确表示通配符,用法如下src $(wildcard.c /usr/src/linux-2.6.24/drivers/char/ip2/.c)vpath 定义make的查找路径多个目录使用空格或者冒号分开1.vpath 为符合pattern的文件指定directories的搜索路径2.vpath 清除符合pattern文件的搜索路径3.vpath清除所有已设置好的搜索路径。vpath pattern path : 符合pattern的文件在path目录搜索。vpath pattern : 清除pattern指定的文件搜索路径vpath : 清除所有文件搜索路径。例1vpath %.h include //指定.h类型文件的搜索路径是includevpath %.cpp src //指定.cpp类型文件的搜索路径是src*** 注意gcc 指定路径还得-Iinclude ***VPATH 变量使用空格或者冒号:将多个目录分开当 make 需要去找寻文件的依赖关系时你可以在文件前加上路径但最好的方法是把一个路径告诉 make让 make 在自动去找VPATH includesrc //指定了makefile的搜索路径函数目录1、(dir)取目录函数2、(dir )取目录函数 2、(dir)取目录函数2、(notdir )取文件函数3、 $(suffix ) 取后缀函数4、 $(basename )取前缀函数5、(addsuffix,)加后缀函数6、(addsuffix ,)加后缀函数 6、(addsuffix,)加后缀函数6、(addprefix ,)加前缀函数7、 $(join ,)连接函数字符串subst: 字符串替换函数patsubst: 模式字符串替换函数strip: 去空格函数findstring: 查找字符串函数filter: 过滤函数filter-out: 反过滤sort: 排序函数word: 取单词函数wordlist: 取单词串函数words: 单词个数统计函数firstword: 首单词函数函数函数需要在目标时候执行判断文件目录是否存在 ??test $(shell if [ -d $(DIR_TEST) ]; then echo “exist”; else echo “noexist”; fi)如果是判断文件修改[ -d $(DIR_TEST) ] 成 [ -f xxx ]调试打印变量1,使用info/warning/error增加调试信息方法1: $(info, “here add the debug info”) – info后面没有逗号但是此不能打印出.mk的行号方法2: $(warning “here add the debug info”)方法3: $(error “error: this will stop the compile”)这个可以停止当前makefile的编译方法4: 打印变量的值$(info $(TARGET_DEVICE) )2,使用echo增加调试信息***echo只能在target后面的语句中使用且前面是个TAB ***方法1 echo “start the compilexxxxxxxxxxxxxxxxxxxxxxx”方法2: echo $(files)例子1all:(BUILDDIR)/(BUILD_DIR)/(BUILDD​IR)/(TARGET).exeecho “…”例子2$(info haha)all:$(info haha1)target1:$(info $(TARGET))、FAQ如何编写函数define func1echo “my name is $(0)”endef调用test :$(call func1)$(call func2, value1)PHONY当前目录下存在clean,和test文件。当声明.PHONY:clean后忽略clean文件的存在直接执行命令所以test文件被删除了数组拼接a bif 语句如何写分在目标外还是目标内***目标外 ***关键字前边一定要有tab#这个ifeq else endif在target 外部关键字前边一定要有tab ifeq (aaa,bbb) #内容前可以有空格如果是tab时解析为命令 #变量前可以多个空格 LIBS -laaa else #echo test LIBS -lbbb endif目标内可以shell 或非shellifeq else endif在target 内部关键字前边一定没有tab否则当命令处理。可以有多个空格cubemx 如何方案cubemx 的makefile,可以添加与外部目录 Code, 将Code的.c .h链接过去对于外部库 定义 MODBUS ONFATFS ON这些变量判断如果有库的情况下 添加MODBUS_LIB_ON 还可以增加库文件是否存在的判断是否构建库*** 定义平台的相关函数 ***window平台 类uinix平台注意 引号类型pwdifeq($(shell uname),)ifeq($(OS),Windows_NT)export HOST_PLATFORMWindowsexport RM_DIR:rd/s/q export RM_FILE:del export MKDIR:mkdir export FIND:dir/s/b export FIND_FILE:$(FIND)/a:-d export FIND_DIR:$(FIND)/a:d export LS:dir/b export CAT:type export DELIMITER:\\ export DELIMITER_S:$(subst/,\,/)else$(error OS not defined)endifelseifeq($(shell uname),Darwin)export HOST_PLATFORMMacOSelseexport HOST_PLATFORMUnix-Likeexport RM_FILE:rm-rf export RM_DIR:rm-f export MKDIR:mkdir export FINDfind pwd-name export FIND_FILEfind pwd-type f-name export FIND_DIRfind pwd-type d-name export LS:ls export CAT:cat export DELIMITER:/export DELIMITER_S:/endif endif工具链定义PREFIX:arm-none-eabi-# gcc 编译器 bin 路径可以在 make 命令中通过 GCC_PATH 变量定义(make GCC_PATHxxx)# 可以将其添加到 PATH 环境变量中。 ifdef GCC_PATH export CC:$(GCC_PATH)/$(PREFIX)gcc export AS:$(GCC_PATH)/$(PREFIX)gcc-x assembler-with-cpp export CP:$(GCC_PATH)/$(PREFIX)objcopy export SZ:$(GCC_PATH)/$(PREFIX)size export NM:$(GCC_PATH)/$(PREFIX)nmelseexport CC:$(PREFIX)gcc export AS:$(PREFIX)gcc-x assembler-with-cpp export CP:$(PREFIX)objcopy export SZ:$(PREFIX)size export NM:$(PREFIX)nm endif export HEX:$(CP)-O ihex export BIN:$(CP)-O binary-S搜索头文件目录export TEST_C_INCLUDES:$(addprefix-I,$(sort $(dir $(filter-out $(ROOT_DIR)/platform%,$(subst \,/,$(shell $(FIND_FILE)*.h))))$(filter-out $(ROOT_DIR)/platform%,$(subst \,/,$(shell $(FIND_DIR)inc)))))export BUILD_C_INCLUDES:$(addprefix-I,$(realpath $(addprefix platform/$(PLATFORM)/,$(patsubst-I%,%,$(C_INCLUDES)))))export BUILD_C_INCLUDES$(TEST_C_INCLUDES)C_SOURCES_FIND :(subst /,(subst \,/,(subst/,(shell findpwd-type f -name *.c))C_SOURCES_FIND :(subst /,(subst \,/,(subst/,(shell $(FIND) /a:-d *.c))文件路径 两种方式请注意c/code/srcc:/code/src搜索源文件注意文件路径类型 搜当前目录下C_SOURCES_FIND:$(subst \,/,$(shell $(FIND_FILE)*.c))条件语句if ifeq ifneqendsatge:# if[-f $(OBJ_DIR)/$(TARGET).elf];then \ # mv $(OBJ_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).elf;\ # fi # echo-e$(DONE_COLOR)::::::::::: BUILD [DONE] :::::::::::$(NO_COLOR) fileaa OBJ$(if$(file),$(file),main.c)# ifeq($(DEBUG),1)# CFLAGS-g-gdwarf-2# endif循环语句foreach forbuild2:echo easylogger build2 (foriin$(C_SOURCES);do\ echo 000000000 $$i ;\ echo $($$i:.c.o);\ done)数据处理foreach 用在非targetnames:a b c d files:$(foreach n,$(names),$(n).o)$(foreachvar,list,text)all:fornameinecho $(files)|sed s/.exe//g; \do\ rm-f$$name.o;\ done用于执行target do 前后一定留有空格#for循环格式 listone two three four test1:foritemin$(list);do\ echo*** $$item;\ done forvarin$(list);doecho--- $$var;done # foreach循环格式 test2:$(foreach x,$(list),\ echo $x;\)$(foreach x,$(list),echo $x;)# 此处分号至关重要
返回列表