首页 > 编程语言 >[C++]Makefile概要

[C++]Makefile概要

时间:2023-01-29 18:35:13浏览次数:40  
标签:SRC 概要 ## Makefile LIST C++ echo banana 函数

#### Makefile 变量和赋值符 ##延迟赋值:  =  变量的正常设置, 但值字段中提到的任何其他变量都在使用变量时用其值递归展开, 而不是声明变量时的值 ##  延迟变量使用[=]操作符进行赋值, 在make解析Makefile阶段不会立即展开, 而是等到实际使用这个变量时才展开, 获得其真正的值.延迟展开变量一般用在规则的命令行中 ##立即赋值: := 通过简单的内部值扩展来设置变量-在声明时扩展变量内的值. ##  立即变量使用[:=]操作符进行赋值, 在解析阶段就直接展开了, 顾名思义, 立即展开变量.立即变量一般用在规则中的目标、目标依赖中. ##条件赋值: ?= 一个变量如果没有被定义过, 就直接给它赋值; 如果之前被定义过, 那么这条赋值语句就什么都不做. ## 相当于: ## ifeq ($(origin VARIABLE), undefined) ##   VARIABLE = value ## endif ##追加赋值: += 一个变量以前已经被赋值, 现在想给它增加新的值, 此时可以使用+=追加赋值. ##  OBJS = hello.o ##  OBJS += module.o ##  等价于: OBJS = hello.o module.o
#### Makefile 通配符 ## 在Makefile中可以使用的通配符有: * 、? 、[…]. ## 在Makefile中, 通配符主要用在两个场合: ## 用在规则的目标和依赖中: make在读取Makefile时会自动对其进行匹配处理(通配符展开).如: ## test: *.o ##    gcc -o $@ $^ ## *.o: *.c ##     gcc -c $ ## 用在规则的命令中: 通配符的通配处理在shell执行命令时完成.如: ## clean: ##     rm -f *.o ## 除了以上两种情况, 在其他地方都不能直接使用通配符.需要一些函数(如wildcard)来实现.


#### Makefile 自动变量 ## $@: 目标 ## $^: 所有目标依赖 ## $<: 目标依赖列表中的第一个依赖 ## $?: 所有目标依赖中有更新的文件 ## $(@D): 表示目标文件的目录部分 ## $(@F): 表示目标文件的文件名部分 ## $(*D): 在模式匹配中, 表示目标模式中%的目录部分 ## $(*F): 在模式匹配中, 表示目标模式中%的文件名部分 ## -: 告诉make在编译时忽略所有的错误 ## @: 告诉make在执行命令前不要显示命令,关闭回声.也可以使用make -s参数
#### 环境变量 ## make在解析Makefile中还会引入一些系统环境变量, 如编译参数CFLAGS、SHELL、MAKE等. ## 这些变量在make开始运行时被载入到Makefile文件中, 因为是全局性的系统环境变量, 所以这些变量对所有的Makefile都有效. ## 若Makefile中有用户自定义的同名变量, 系统环境变量将会被用户自定义的变量覆盖.可用?=进行赋值.
#### 条件判断 ##ifeq 关键字 ##  mode = debug ##  ifeq ($(mode),debug) ##ifneq 关键字 ##  mode = debug ##  ifneq ($(mode),) ##ifdef 关键字 ##  mode = ##  ifdef mode ##ifndef 关键字 ##  mode = ##  ifndef mode ##没有else if, 可以用嵌套实现.
#### 函数 ## 函数主要分为两类: make内嵌函数和用户自定义函数. ##   对于GNU make内嵌的函数, 直接引用就可以了; ##   对于用户自定义的函数, 要通过make的call函数来间接调用. ## 函数和参数列表之间要用空格隔开, 多个参数之间使用逗号隔开. ## 如果在参数中引用了变量, 变量的引用建议和函数引用使用统一格式: 要么是一对小括号$(XXX), 要么是一对大括号${XXX}.
##扩展通配符函数: wildcard ## 列出当前目录下所有符合PATTREN模式的文件名 ##  $(wildcard PATTERN) ##  其中PATTREN可以使用shell能识别的通配符: ?、*等. ##   .PHONY: all ##   LIST  = $(wildcard *.c) ##   all: ##       @echo "LIST = $(LIST)" ##   运行结果为: ##   add.c  add.h  hello.c  main.c  makefile  sub.c  sub.h ##   LIST = hello.c main.c add.c sub.c
##subst函数 ## subst函数用来实现字符串的替换, 将字符串text中的old替换为new. ## $(subst old,new,text) ## OBJ = $(subst .c,.o,$(SRC))
##patsubst函数 ## patsubst函数主要用来模式替换: 使用通配符 % 代表一个单词中的若干字符. ##  目录下的所有.c文件名转换为以.o目标文件名 ##  OBJ = $(patsubst %.c, %.o, $(SRC))
##模式匹配替换(写法不同, 功能等同于patsubst函数) ##  SRC := main.c sub.c ##  OBJ := $(SRC:%.c=%.o) 结果:OBJ = main.o sub.o
##strip函数 ## strip函数是一个去空格函数. 空字符包括: 空格、多个空格、tab等不可显示的字符. ##   STR =     hello a    b   c   ##   STRIP_STR = $(strip $(STR)) 结果: STRIP_STR = hello a b c
##findstring 函数 ## findstring函数用来查找一个字符串.使用格式如下: ## $(findstring FIND, IN) ## findstring函数会在字符串IN中查找"FIND"字符串, 如果找到, 则返回字符串FIND, 否则, 返回空. ##   STR =     hello a    b   c   ##   FIND = $(findstring hello, $(STR)) ##   运行结果为: FIND = hello
##filter 函数 ## filter函数用来过滤掉一个指定的字符串, 使用格式如下: ## $(filter PATTERN…,TEXT) ## filter函数用来过滤掉字符串TEXT中所有不符合PATTERN模式的单词, 只留下符合PATTERN格式的单词. ##   FILE = a.c b.h c.s d.cpp   ##   SRC = $(filter %.c, $(FILE)) ##   运行结果为: SRC = a.c
##filter-out 函数 ## filer-out函数是一个反过滤函数, 功能和filter函数恰恰相反: ##   该函数会过滤掉所有符合PATTERN模式的单词, 保留所有不符合此模式的单词. ##   FILE = a.c b.h c.s d.cpp   ##   SRC = $(filter-out %.c, $(FILE)) ##   运行结果为: SRC = b.h c.s d.cpp
##sort函数: 单词排序 ## $(sort LIST) ## sort函数对字符串LIST中的单词以首字母为准进行排序, 并删除重复的单词. ##   LIST = banana pear apple peach apple orange ##   SRC = $(sort $(LIST)) ##   运行结果为: STR = apple banana orange peach pear
##word函数: 取单词 ## word函数的作用是从一个字符串TEXT中, 按照指定的数目N取单词: ##  $(word N,TEXT) ## 函数的返回值是字符串TEXT中的第N个单词.如果N的值大于字符串中单词的个数, 返回空; 如果N为0, 则出错. ##   LIST = banana pear apple peach orange ##   word1 = $(word 1, $(LIST)) ##   word5 = $(word 5, $(LIST)) ##   word6 = $(word 6, $(LIST)) ##   运行结果为: ##   word1 = banana ##   word5 = orange ##   word6 =
##wordlist函数: 取字串 ## wordlist函数用来从一个字符串TEXT中取出从N到M之间的一个单词串: ##  $(wordlist N, M, TEXT) ## N和M都是从1开始的一个数字, 函数的返回值是字符串TEXT中从N到M的一个单词串. ## 当N比字符串TEXT中的单词个数大时, 函数返回空. ##   LIST = banana pear apple peach orange ##   sub_list = $(wordlist 1, 3, $(LIST)) ##   运行结果为: ##   sub_list = banana pear apple
##words函数: 统计单词数目 ## words函数用来统计一个字符串TEXT中单词的个数: ##  $(words TEXT) ## words函数的返回值为字符串TEXT中单词的个数. ##   LIST = banana pear apple peach orange ##   @echo "LIST len = $(words $(LIST)) ##   运行结果为: ##   LIST len = 5
##firstword函数: 取首个单词 ## firstword函数用来取一个字符串中的首个单词. ##  $(firstword NAMES…) ## firstword函数其实就相当于$(word 1,TEXT): ##   LIST = banana pear apple peach orange ##   @echo "first word = $(firstword $(LIST))" ##   运行结果为: ##   first word = banana
##dir函数: 取路径名的目录 ## dir函数用来从一个路径名中截取目录的部分. ##  $(dir NAMES…) ## dir函数会从NAMES文件名序列中, 取出各个文件路径名中的目录部分并返回 ##   .PHONY: all ##   LIST = /home/wit/banana.c /usr/include/stdio.h ##   all: ##       @echo "dir = $(dir $(LIST))" ##   运行结果为: ##   dir = /home/wit/ /usr/include/
##notdir函数: 取文件名 ## notdir函数和dir函数实现完全相反的功能: 从一个文件路径名中去文件名, 而不是目录.notdir函数的使用方法和dir函数相同. ##   .PHONY: all ##   LIST = /home/wit/banana.c /usr/include/stdio.h ##   all: ##       @echo "file = $(notdir $(LIST))" ##   运行结果为: ##   file = banana.c stdio.h
##suffix函数: 取文件名后缀 ## suffix函数从一系列文件名序列中, 取出各个文件名的后缀. ## $(suffix NAMES…) ##   .PHONY: all ##   LIST = /home/wit/banana.c /usr/include/stdio.h ##   all: ##       @echo "suffix = $(suffix $(LIST))" ##   运行结果为: ##   suffix = .c .h
##basename函数: 取文件名前缀 ## basename函数从一系列文件名序列中, 取出各个文件名的前缀部分: ## $(basename NAMES…) ## 如果一个文件名中包括多个点号, basename函数返回最后一个点号之前的文件名部分; 如果一个文件名没有前缀, 函数返回空字符串. ##   .PHONY: all ##   LIST = /home/wit/banana.c /usr/include/vmlinux.lds.S ##   all: ##       @echo "basename = $(basename $(LIST))" ##   运行结果为: ##   basename = /home/wit/banana /usr/include/vmlinux.lds
##addsuffix函数: 给文件名加后缀 ## addsuffix函数的作用是: 给文件列表中的每个文件名添加后缀SUFFIX ## $(addsuffix SUFFIX, NAMES…) ##   .PHONY: all ##   LIST = apple banana peach ##   all: ##       @echo "addsuffix = $(addsuffix .c, $(LIST))" ##   运行结果为: ##   addsuffix = apple.c banana.c peach.c
##addprefix函数: 给文件名加前缀 ## addprefix函数的作用是: 给文件列表中的每个文件名添加一个前缀PREFIX ## $(addprefix PREFIX, NAMES…) ##   .PHONY: all ##   LIST = apple.c banana.c peach.c ##   all: ##       @echo "addsuffix = $(addprefix /home/wit/, $(LIST))" ##   运行结果为: ##   addsuffix = /home/wit/apple.c /home/wit/banana.c /home/wit/peach.c
##join函数: 单词连接 ## 将字符串LIST1和字符串LIST2的各个单词依次连接, 合并为新的单词构成的字符串 ## $(join LIST1,LIST2) ##   .PHONY: all ##   LIST1 = apple banana peach ##   LIST2 = .c .h .s ##   LIST  = $(join $(LIST1), $(LIST2)) ##   all: ##       @echo "LIST = $(LIST)" ##   运行结果为: ##   LIST = apple.c banana.h peach.s ##   如果两个字符串中的单词个数不相等, 则只合并前面的单词, 剩下的单词不合并.   ---makefile例子
#此项目源文件后缀类型 PROJECTTYPE:=.cpp
#C语言编译器 CC:= gcc #C++编译器 CXX:= g++ #C语言配置参数 CFLAGS?= -g -pedantic -std=c11 -Wall -o #C++配置参数 #CXXFLAGS?= -g -Wall -std=c++14 CXXFLAGS?= -g -std=c++14 -O0
#RM:= rm -rf RM:= del /F /S /Q
#获取当前makefile绝对路径 pes_parent_dir:=$(shell chdir)
target?=VSCodeCPPLearningMakefile.exe BIN:=$(pes_parent_dir)/$(target)
##想编译的文件目录 ##手动输入: 所有目录及子目录都需加上 #SRC_DIRS  = ./util ./Base ./Arithmetic ./DesignPattern/01_FactoryMethod ... ./Modern/ ./Modern/Thread ##递归遍历: #SRC_DIRS := $(shell find ../a -maxdepth 3 -type d) $(shell find ../b -maxdepth 3 -type d) SRC_DIRS:= $(shell dir /S /AD /B)
##EX_FILES要排除的文件 #EX_FILES = ../a/aa/exa.cpp ../a/bb/exb.cpp EX_FILES:=
##foreach 遍历想编译的源目录, wildcard 获取目录下所有文件并加上后缀.cpp(语法上是为.cpp加上前缀, 前缀为目录下的文件名, 即为文件加后缀) #SRC_FILES  = $(filter-out ${EX_FILES}, $(foreach dir, $(SRC_DIRS), $(wildcard $(addprefix $(dir)/*, .cpp)))) SRC_FILES:=$(filter-out $(EX_FILES), $(foreach dir, $(SRC_DIRS), $(wildcard $(addprefix $(dir)/*, $(PROJECTTYPE)))))
#basename 返回一个字符串. 之前的所有字段,即去掉后缀, 同时addsuffix 加上后缀.o #OBJS = $(addsuffix .o, $(basename $(SRC_FILES))) OBJS=$(patsubst %$(PROJECTTYPE),%.o,$(SRC_FILES))
#头文件搜索路径 INCLUDE_PATH:=$(foreach n,$(SRC_DIRS), -I$(n))
#-c: 生成xxx.o的目标文件 -o: 生成可执行程序的目标文件 $(BIN):$(OBJS)     @echo bulding....     @$(CXX) $(CXXFLAGS) CPPLearning.cpp $(OBJS) -o $(target)     @echo created file: $(target)
#   @$(CXX) -o $(target) $(OBJS)  $(CXXFLAGS) #   @$(CXX) -o $@ $^  $(CXXFLAGS) #   @$(CXX) $^ -o $@ #   $(COMPILE.CXX) -c $^ -o $@
#$(SRC_DIRS)/%.o:$(SRC_DIRS)/%.cpp $(OBJS): $(SRC_FILES) #   @$(CXX) -c -o %.o %.cpp
#.PHONY 伪目标, 目标文件名存在也可以执行 .PHONY: clean show cleanexe clean:     @echo 'Cleaning up all files...'     @-$(RM) $(target)     @-$(RM) *.o     @echo 'Clean done' cleanexe:     @echo 'Cleaning up exe file...'     @-$(RM) $(target)     @echo 'Clean done'
show:     @echo target======     @echo    $(target)     @echo SRC_DIRS====     @echo    $(SRC_DIRS)     @echo SRC_FILES===     @echo    $(SRC_FILES)     @echo EX_FILES====     @echo    $(EX_FILES)     @echo OBJS========     @echo    $(OBJS)

标签:SRC,概要,##,Makefile,LIST,C++,echo,banana,函数
From: https://www.cnblogs.com/TonyZhao/p/17073526.html

相关文章

  • 奇巧:C++ 调用python方法
    方法一:使用python提供给C/C++的API主流方法将python程序编程文本形式的动态链接库,在c/c++程序中调用其中定义的函数。本质上是在c++中启动了一个python解释器,由......
  • C++ Day10 统计圣经文本的词频 &文本查询程序
    一、编程题--统计圣经出现的单词以及词频统计一篇英文(The_Holy_Bible.txt)文章中出现的单词和词频,输入:某篇文章的绝对路径;输出:词典(词典中的内容为每一行都是一个“单词......
  • VC++的Unicode编程
    一、什么是Unicode先从ASCII说起,ASCII是用来表示英文字符的一种编码规范。每个ASCII字符占用1个字节,因此,ASCII编码可以表示的最大字符数是255(00H—FFH)。其实,英文字符......
  • gdb同时调试python和c++
    说明:当我们的python程序的一些函数的后端实现为C++时(比如Pytorch,TensorFlow或tvm等)可以使用当前方法调试。有两种方式可以安装调试环境:一.搭建环境有两种方式搭建......
  • Python和C++联合调试
     python和c++分别在Linux和Windows下联合调试首先创建一个python测试项目和一个c++拓展项目一、在Windows下进行调试1.编译器安装2.C拓展模块安装3.调试......
  • ubuntu下C++如何调用python程序,gdb调试C++代码
    Linux下gdb调试C++代码:http://jingyan.baidu.com/article/acf728fd464984f8e410a369.html主要ubuntu下使用C++调用Python:#python代码:(processing_module.py)importcv2......
  • C++ 设计模式--模板方法Template Method
    1.定义定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。TemplateMethod使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法的某......
  • 【C++】char使用汇总
    一、char*字符串格式化根据输入的int型参数,与字符串拼接。char*可以替换为char[]intnum=1;chartmpStr[5];sprintf(tmpStr,"Test%d",num);//tmpStr=Test1......
  • 【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++
    第十章堆栈:::hljs-center目录第十章堆栈●前言●一、堆栈是什么?1.简要介绍●二、堆栈操作的关键代码段1.类型定义2.顺序栈的常用操作3.链式栈的常用......
  • A+B Problem C++
    前言继上次发表的A+BProblemC语言后,今天我们来学习一下A+BProblemC++正文什么是C++?C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的......