patsubst(patsubst不带参数)
makefile当中foreach能不能和patsubst一起使用
makefile当中foreach能不能和patsubst一起使用
不是,这个只是做字符串转换,比方说你在makefile里定义了所有要编译的源文件
SRCC = a.c b.c c.c
那么你可以用 patsubst 这个函数来将 SRCC 里存放的源文件名字转换成对应的目标文件名,
OBJS = $(patsubst %.c, %.o, $(SRCC))
此时 OBJS 的内容就是 a.o b.o c.o
make跟pat发音a一样吗
字母a在两个单词中的发音不一样。第一个单词里面发的是字母a的开音节/ei/,第二个单词里面发的是什么a的闭音节/ae/。
Linux下 Makefile中的 patsubst 的问题!!!!!!!高手快来
不是,这个只是做字符串转换,比方说你在makefile里定义了所有要编译的源文件
SRCC
=
a.c
b.c
c.c
那么你可以用
patsubst
这个函数来将
SRCC
里存放的源文件名字转换成对应的目标文件名,
OBJS
=
$(patsubst
%.c,
%.o,
$(SRCC))
此时
OBJS
的内容就是
a.o
b.o
c.o
patsubst:模式字符串替换 我想问下什么是模式字符串啊??这是一道linux的知识。
patsubst 应该是 makefile 里的一个函数 (如果你问的 patsubst 是其他语言里的,那就别看下面的了)
比方说你在 makefile 里定义了一个变量,内容是一堆 .c 文件的的名字,如
SRC = aaa.c bbb.c my.c his.c
你可以用 patsubst 根据 某种模式,将这些名字改成另外的,比如将这些 .c 文件的名字变成 .s 为后缀的名字:
NEW = $(patsubst "%.c", "%.s", ${SRC})
这样 NEW 这个变量中,就记录了 aaa.s bbb.s my.s his.s 这些后缀名为 .s 的文件。 上面命令中的模式字符串就是 "%.c" 或 "%.s", 而其中的 "%" 就是特殊的匹配字符,对于 aaa.c 这个字符串来说, "%.c" 中的% 就匹配 aaa。 这个很像我们在 bash 或者 dos 下用 *.c 匹配所有 .c 文件时候的那个 *
Linux平台Makefile文件的编写基础篇
目的:
基本掌握了 make 的用法,能在Linux系统上编程。
环境:
Linux系统,或者有一台Linux服务器,通过终端连接。一句话:有Linux编译环境。
准备:
准备三个文件:file1.c, file2.c, file2.h
file1.c:
#include
#include "file2.h"
int main()
{
printf("print file1$$$$$$$$$$$$ ");
File2Print();
return 0;
}
file2.h:
#ifndef FILE2_H_
#define FILE2_H_
#ifdef __cplusplus
extern "C" {
#endif
void File2Print();
#ifdef __cplusplus
}
#endif
#endif
file2.c:
#include "file2.h"
void File2Print()
{
printf("Print file2********************** ");
}
基础:
先来个例子:
有这么个Makefile文件。(文件和Makefile在同一目录)
=== makefile 开始 ===
helloworld:file1.o file2.o
gcc file1.o file2.o -o helloworld
file1.o:file1.c file2.h
gcc -c file1.c -o file1.o
file2.o:file2.c file2.h
gcc -c file2.c -o file2.o
clean:
rm -rf *.o helloworld
=== makefile 结束 ===
一个 makefile 主要含有一系列的规则,如下:
A: B
(tab)
(tab)
每个命令行前都必须有tab符号。
上面的makefile文件目的就是要编译一个helloworld的可执行文件。让我们一句一句来解释:
helloworld : file1.o file2.o: helloworld依赖file1.o file2.o两个目标文件。
gcc File1.o File2.o -o helloworld: 编译出helloworld可执行文件。-o表示你指定 的目标文件名。
file1.o : file1.c: file1.o依赖file1.c文件。
gcc -c file1.c -o file1.o: 编译出file1.o文件。-c表示gcc 只把给它的文件编译成目标文件, 用源码文件的文件名命名但把其后缀由“.c”或“.cc”变成“.o”。在这句中,可以省略-o file1.o,编译器默认生成file1.o文件,这就是-c的作用。
file2.o : file2.c file2.h
gcc -c file2.c -o file2.o
这两句和上两句相同。
clean:
rm -rf *.o helloworld
当用户键入make clean命令时,会删除*.o 和helloworld文件。
如果要编译cpp文件,只要把gcc改成g++就行了。
写好Makefile文件,在命令行中直接键入make命令,就会执行Makefile中的内容了。
到这步我想你能编一个Helloworld程序了。
上一层楼:使用变量
上面提到一句,如果要编译cpp文件,只要把gcc改成g++就行了。但如果Makefile中有很多gcc,那不就很麻烦了。
第二个例子:
=== makefile 开始 ===
OBJS = file1.o file2.o
CC = gcc
CFLAGS = -Wall -O -g
helloworld : $(OBJS)
$(CC) $(OBJS) -o helloworld
file1.o : file1.c file2.h
$(CC) $(CFLAGS) -c file1.c -o file1.o
file2.o : file2.c file2.h
$(CC) $(CFLAGS) -c file2.c -o file2.o
clean:
rm -rf *.o helloworld
=== makefile 结束 ===
这里我们应用到了变量。要设定一个变量,你只要在一行的开始写下这个变量的名字,后 面跟一个 = 号,后面跟你要设定的这个变量的值。以后你要引用 这个变量,写一个 $ 符号,后面是围在括号里的变量名。
CFLAGS = -Wall -O –g,解释一下。这是配置编译器设置,并把它赋值给CFFLAGS变量。
-Wall: 输出所有的警告信息。
-O: 在编译时进行优化。
-g: 表示编译debug版本。
这样写的Makefile文件比较简单,但很容易就会发现缺点,那就是要列出所有的c文件。如果你添加一个c文件,那就需要修改Makefile文件,这在项目开发中还是比较麻烦的。
再上一层楼:使用函数
学到这里,你也许会说,这就好像编程序吗?有变量,也有函数。其实这就是编程序,只不过用的语言不同而已。
第三个例子:
=== makefile 开始 ===
CC = gcc
XX = g++
CFLAGS = -Wall -O –g
TARGET = ./helloworld
%.o: %.c
$(CC) $(CFLAGS) -c lt; -o [email?protected]
%.o:%.cpp
$(XX) $(CFLAGS) -c lt; -o [email?protected]
SOURCES = $(wildcard *.c *.cpp)
OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))
$(TARGET) : $(OBJS)
$(XX) $(OBJS) -o $(TARGET)
chmod a+x $(TARGET)
clean:
rm -rf *.o helloworld
=== makefile 结束 ===
函数1:wildcard
产生一个所有以 '.c' 结尾的文件的列表。
SOURCES = $(wildcard *.c *.cpp)表示产生一个所有以 .c,.cpp结尾的文件的列表,然后存入变量 SOURCES 里。
函数2:patsubst
匹配替换,有三个参数。第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的列表。
OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCES)))表示把文件列表中所有的.c,.cpp字符变成.o,形成一个新的文件列表,然后存入OBJS变量中。
%.o: %.c
$(CC) $(CFLAGS) -c lt; -o [email?protected]
%.o:%.cpp
$(XX) $(CFLAGS) -c lt; -o [email?protected]
这几句命令表示把所有的.c,.cpp编译成.o文件。
这里有三个比较有用的内部变量。 [email?protected] 扩展成当前规则的目的文件名, lt; 扩展成依靠 列表中的第一个依靠文件,而 $^ 扩展成整个依靠的列表(除掉了里面所有重 复的文件名)。
chmod a+x $(TARGET)表示把helloworld强制变成可执行文件。
makefile foreach 中能掉用函数么
在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具
有智能。make所支持的函数也不算很多,不过已经足够我们的操作了。函数调用后,函
数的返回值可以当做变量来使用。
一、函数的调用语法
函数调用,很像变量的使用,也是以“$”来标识的,其语法如下:
$(function arguments )
或是
${function arguments}
这里,function就是函数名,make支持的函数不多。arguments是函数的参数,参数
间以逗号“,”分隔,而函数名和参数之间以“空格”分隔。函数调用以“$”开头,以圆
括号或花括号把函数名和参数括起。感觉很像一个变量,是不是?函数中的参数可以使
用变量,为了风格的统一,函数和变量的括号最好一样,如使用“$(substa,b,$(x))”这
样的形式,而不是“$(substa,b,${x})”的形式。因为统一会更清楚,也会减少一些不必
要的麻烦。
还是来看一个示例:
comma:= ,
empty:=
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
在这个示例中,$(comma)的值是一个逗号。$(space)使用了$(empty)定义了一个空格,
$(foo)的值是“a b c”,$(bar)的定义用,调用了函数“subst”,这是一个替换函数,这
个函数有三个参数,第一个参数是被替换字串,第二个参数是替换字串,第三个参数
是替换操作作用的字串。这个函数也就是把$(foo)中的空格替换成逗号,所以$(bar)的值
是“a,b,c”。
二、字符串处理函数
$(subst from,to,text )
名称:字符串替换函数——subst。
功能:把字串text中的from字符串替换成to。
返回:函数返回被替换过后的字符串。
示例:
$(subst ee,EE,feet on the street),
把“feetonthestreet”中的“ee”替换成“EE”,返回结果是“fEEtonthestrEEt”。
$(patsubst pattern,replacement,text )
名称:模式字符串替换函数——patsubst。
功能:查找text中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否
符合模式pattern,如果匹配的话,则以replacement替换。这里,pattern可以包括
通配符“%”,表示任意长度的字串。如果replacement中也包含“%”,那么,
replacement中的这个“%”将是pattern中的那个“%”所代表的字串。(可以用“\”
来转义,以“\%”来表示真实含义的“%”字符)
返回:函数返回被替换过后的字符串。
示例:
$(patsubst %.c,%.o,x.c.c bar.c)
把字串“x.c.cbar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.obar.o”
备注:
这和我们前面“变量章节”说过的相关知识有点相似。如:
“$(var:pattern=replacement )”
相当于
“$(patsubst pattern,replacement,$(var))”,
而“$(var:suffix=replacement)”
则相当于
“$(patsubst %suffix,%replacement,$(var))”。
例如有:objects=foo.obar.obaz.o,
那么,“$(objects:.o=.c)”和“$(patsubst%.o,%.c,$(objects))”是一样的。
$(strip string )
名称:去空格函数——strip。
功能:去掉string字串中开头和结尾的空字符。
返回:返回被去掉空格的字符串值。
示例:
$(strip a b c )
把字串“abc”去到开头和结尾的空格,结果是“abc”。
$(findstring find,in )
名称:查找字符串函数——findstring。
功能:在字串in中查找find字串。
返回:如果找到,那么返回find,否则返回空字符串。
示例:
$(findstring a,a b c)
$(findstring a,b c)
第一个函数返回“a”字符串,第二个返回“”字符串(空字符串)
$(filter pattern...,text )
名称:过滤函数——filter。
功能:以pattern模式过滤text字符串中的单词,保留符合模式pattern的单词。可
以有多个模式。
返回:返回符合模式pattern的字串。
示例:
sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
cc $(filter %.c %.s,$(sources)) -o foo
$(filter %.c %.s,$(sources))返回的值是“foo.c bar.c baz.s”。
$(filter-out pattern...,text )
名称:反过滤函数——filter-out。
功能:以pattern模式过滤text字符串中的单词,去除符合模式pattern的单词。可
以有多个模式。
返回:返回不符合模式pattern的字串。
示例:
objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o
$(filter-out $(mains),$(objects)) 返回值是“foo.o bar.o”。
$(sort list )
名称:排序函数——sort。
功能:给字符串list中的单词排序(升序)。
返回:返回排序后的字符串。
示例:$(sortfoobarlose)返回“barfoolose”。
备注:sort函数会去掉list中相同的单词。
$(word n,text )
名称:取单词函数——word。
功能:取字符串text中第n个单词。(从一开始)
返回:返回字符串text中第n个单词。如果n比text中的单词数要大,那么返回
空字符串。
示例:$(word2,foobarbaz)返回值是“bar”。
$(wordlist s,e,text )
名称:取单词串函数——wordlist。
功能:从字符串text中取从s开始到e的单词串。s和e是一个数字。
返回:返回字符串text中从s到e的单词字串。如果s比text中的单词数要大,
那么返回空字符串。如果e大于text的单词数,那么返回从s开始,到text结束
的单词串。
示例:$(wordlist2,3,foobarbaz)返回值是“barbaz”。
$(words text )
名称:单词个数统计函数——words。
功能:统计text中字符串中的单词个数。
返回:返回text中的单词数。
示例:$(words,foobarbaz)返回值是“3”。
备注:如果我们要取text中最后的一个单词,我们可以这样:$(word $(words
text ),text )。
$(firstword text )
名称:首单词函数——firstword。
功能:取字符串text中的第一个单词。
返回:返回字符串text的第一个单词。
示例:$(firstwordfoobar)返回值是“foo”。
备注:这个函数可以用word函数来实现:$(word1,text)。
以上,是所有的字符串操作函数,如果搭配混合使用,可以完成比较复杂的功能。这里,
举一个现实中应用的例子。我们知道,make使用“VPATH”变量来指定“依赖文件”的
搜索路径。于是,我们可以利用这个搜索路径来指定编译器对头文件的搜索路径参数
CFLAGS,如:
override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
如果我们的“$(VPATH)”值是“src:../headers”,那么“$(patsubst %,-I%,$(subst :, ,
$(VPATH)))”将返回“-Isrc -I../headers”,这正是 cc 或 gcc 搜索头文件路径的参数。