1. 首页 > 热点 >

跟我一起写makefile_跟我一起写makefile网盘

C和C++的makefile文件编写规则一样么,或者说两者有何不同?

target也就是一个目标文件,可以是Object

这个依赖于编译器,而不是依赖于编程语言。

跟我一起写makefile_跟我一起写makefile网盘跟我一起写makefile_跟我一起写makefile网盘


-rm $(COBJS) $(CPPOBJS)

不同版本的make的编写规则是不一样的,比如说HP-UX下的make和GNU-make就是两种规则,前者支持的功能很少,后者则非常全。

makefile 对于 没有IDE的开发 非常重要。跟 c/c++无关。

写makefile真的很有意思,他是个自动处理机。我学了学,终于把一些非常复杂的makefile搞懂了。

624433109# 链接为最终目标

makefile是干什么用的?

Ubuntu下面Makefile的使用方法

运行可执行文件hello

./hello

移除文件 rm hello

编译文件得到可执行文件的同时,保留产生的中间文件

g++ -se-temps hello_world.cpp -o hello

单个文件编译过程:

实际的编译过程:预处理,对应临时文件hello_world.ii

cat preprocessed.ii

预处理的工作主要包含去掉注释,然后将我们include的库tack上,以上过程使我们自己主动调用预处理器的过程

cat hello_world.ii

则展示了我们在第5)中编译时保留的中间文件,两者是一样的

实际的编译过程:这是真正的编译过程compilation step,对应临时文件hello_world.s(assembly code)

我们自己把.ii文件进行assembly code得到.s的方法。

g++ -S preprocessed.ii -o complied.s

.s文件是高级语言和机器语言之间的中间环节

实际的编译过程:Assembly,将.s对应的assembly code转换成.o对应的机器语言的过程,也叫machine-readable code或者object code

让编译器将.s文件assembly起来

g++ -c complied.s -o assembled.o

实际的编译过程:一步Linking,产生最终的可执行文件。

"Undefined reference" errors are pretty much always linking errors, and you will probably he them. Remember this.

我们通过连接一堆.o文件,得到.exe文件的过程,命令:

g++ assembled.o -o hello_manual

多个文件编译过程:

举例,如果我们有定义一个class,然后我们的文件中包含dog.hpp,dog.cpp和main.cpp三个文件,然后我们只使用以下两个命令:

g++ -c main.cpp -o main.o

g++ main.o dog_program

g++ -c main.cpp -o main.o

g++ -c dog.cpp

g++ dog.o main.o -o dog_program

的话,就不会出错。

我们如果修改main.cpp中的内容的话,我们只需要重新用一个连接命令。但是,如果我们修改了dog class本身的内容的话,例如添加一个函数,我们就需要重新产生object file of dog.cpp,然后重新连接。

关于Make的介绍

用自己常用的记事本创建一个Makefile,并注意大小写。在program对应的目录下面。

gedit Makefile

Makefile里面语句的书写规则是

Target: tgt_dependency1 tgt_dependency2 ……

Comm/////main.cppand

所以dog.o和main.o对应的语句分别是:

dog.o: dog.hpp dog.cpp

g++ -c dog.cpp

在Makefile中Tab是很重要的,所以不要忘记在command对应的第二行加Tab

Makefile的编译顺序

如果Makefile中有如下语句

animal_assembly : moose goose cat

cmakefile文件主要有以下五种组成部分。显式规则:显式规则说明了生成一个或多个目标文件的方法和步骤。这是在编写makefile文件时明显指出的,包括要生成的文件、生成文件的依赖文件以及生成的命令等。ommand

moose : antlers hooves fur

comma1.1 Makefile的规则nd

goose : beak wings webbed_feet interest_in_bread

command

cat : whiskers evil_personality

command

我们可以看到animal_assembly的dependency是 moose goose cat。如果文件夹中存在moose goose cat的话,make命令只需要执行句就可以了。如果文件夹中缺少moose goose cat中的一个或者几个,make命令执行的时候,需要先找到moose goose cat的生成方法,然后执行对应的命令,执行animal_assembly生成的命令。

moose : antlers hooves fur

command

animal_assembly : moose goose cat

command

goose : beak wings webbed_feet interest_in_bread

command

cat : whiskers evil_personality

command

如果Makefille是以上形式的话,我们只运行make的话,Makefile会只执行句,因为句的dependency都存在了,所以只把moose生成的命令执行完就好了。如果我们要生成animal_assembly,就要运行命令make animal_assembly。所以,我们需要把最重要的命令,我们最重要生成的object file对应的命令放在行。

所以我们的dog_program的完整的Makefile文件应该是:

dog_program: dog.o main.o

g++ dog.o main.o -o dog_program

dog.o: dog.hpp dog.cpp

g++ -c dog.cpp

在Makefile的写clean语句。

rm dog_program .o

然后我们在命令窗口运行make clean的话,就会删除文件夹中生成的可执行文件,和所有过程中产生的副产品。

对于Makefile中的dependency list,我们需要将每个object file的dependency list都写好。因为make不负责检查文件中的具体的语句,只负责执行Makefile中的语句。

dog_program:

g++ dog.o main.o -o dog_program

dog.o: dog.hpp dog.cpp

g++ -c dog.cpp

如果像上面所示去掉dog_program的dependency list的话,运行make就会出错,因为main是依赖于dog.cpp的。

如果文件中本身就存在dog.o和main.o的话,运行make不会出错,因为make就是先check dog.o main.o是否存在,存在的话就直接运行。

所以,我们如果修改了main.cpp或者dog.cpp的话,我们需要重新生成dog.o和main.o。因为make是不管这个问题的。

make这个命令的功能就是执行Makefile中我们要求执行的语句,对结果没有任何的预期,也不会检查命令有没有问题。所以,我们必须遵守Makefile书写中的一些规则。

all : fill_file_with_nonsense

echo "I he mostly created a lot of junk today!"

fill_file_with_nonsense : create_file

echo "Hello, there is nothing important here" > silly_file

create_file :

touch silly_file touch是Unix中的典型命令,用于生成空的文件

move_file :

mv silly_file silly_file_new_name

delete_file :

rm _file

open_file :

gedit another_silly_file

clean :

touch junk1 junk2 junk3 junk4 junk5

really_clean :

rm junk

如果想体验的更加清楚,就可以运行这个文件中的内容,然后就知道make完全不会管结果是什么,只是没有脑子的执行命令。

Makefile的书写规则。all: 放在句,把所以我们要生成executable依赖的Targets列出来,这样我们需要的所有的文件都可以生成。我们看到all对应的dependency是file_file_with_nonsense,就去找file_file_with_nonsense的生成语句,发现它的dependency是create_file,然后去找create_file的生成语句,就到touch silly_file,touch是Unix中的典型命令,用于生成空的文件。create_file的语句执行完之后,回到file_file_with_nonsense,执行echo "Hello, there is nothing important here" > silly_file,就把"Hello, there is nothing important here" 写入silly_file中,file_file_with_nonsense的语句也执行完之后,我们就返回到all,然后在命令行输出"I he mostly created a lot of junk today!"。

因为其他的target,不在all的dependency list中,也不在all的dependency的dependency当中,所以只能通过make target的形式来调用对应的命令。

Marvelous macros(宏)

一个宏的示例,宏就是Makefile中的variables,用来定义我们需要的作,一些变量之类的

CXX = clang++

FLAGS = -O

$(CXX) $(FLAGS) $? -o $@

clean :

rm hello

CXX,这是一个预定义的宏,default value是g++。这里把CXX定义成clang++了。

FLAGS,这里定义的是-O。FLAGS也不一定非得定义成-o,也可以是some moose he large antlers,但是这样定义的话,就会导致调用的时候出错。

对于上面的文件,我们在命令行输入make的时候,实际运行的是clang++ -O hello_world.cpp -o hello。

如果我们把CXX=clang++这一行删掉的话,在命令行输入make,实际运行的就是g++ -O hello_world.cpp -o hello。

定义好macro宏,我们使用的时候,就要用$(MACRO)这样的形式,这是makefile语言的一种语法。我们注意到MACRO全部用的大写,虽然不是明确规定的,但是通常情况下用大写。

$?和$@是makefile language里面特别的预定义的宏。$?是指的"names of the dependencies(newer than the target)",$@是指的"name of the target"。

CXX = clang++ LD = clang++

CXXFLAGS = -std=c++1y -stdlib=libc++ -c -g -O0 -Wall -Wextra -Werror -pedantic

LDFLAGS = -std=c++1y -stdlib=libc++ -lpng -lc++abi

c语言创建.a库和调用.a库的makefile编写问题

通过以上简要的介绍,你就可以简要的去编写一些更加复杂的makefile来运行你的复杂的程序了。上边讲的只是冰山一角

我在你调用库函数的makefile里没有看到你对libapi.a库的包含,就像你包含动态库用-lpthread一样,你需要包含一下libapi.a静态库,只是它的包含不需要在前面加-l或-L,直接把你的libapi.a的路径和名字加上即可。 形如 gcc -g -c test test.o -lpthread ./libapi.a

因为对于不同的.cpp文件,都要生成一个object 这个我还真不知道,,file,也就是.o文件。所以如果我们用以下命令:

建立五个文件:ex1.c文件,ex2.c文件,ex.h文件,ex.c文件,makefile文件

解释上面的内容:

CFLAGS := -Wall -O2 -c

CFLAGS += -I$(PWD)/include #包含的头文件路径: $(PWD)表示当前路径

LDFLAGS := -lm -lpthread #链接的库文件写在这里

CC := gcc

LD := ld

OBJS := main.o ex.o ex1.o ex2.o #所有的目标文件写在这里。

all:g++ -E hello_world.cpp -o preprocessed.ii $(OBJS)g++ -c main.cpp

$(CC) $(LDFLAGS) -o ex $^ # ex是可编译后生成的可执行程序

rm -f ex

rm -f $(OBJS)

%.o:%.c

$(CC) $(CFLAGS) -o $@ $<

解释这个makefile,这是一部分,我知道这是一个eclipse的工程,解释5到35行

下面是别人的。

1, -include 和c语言的 #include 不多,是把文件插入到当前文件的当前位置。

2, ifneq ($main.o: main.cpp(MAKECMDGOALS),clean) : 如果变量MAKECMDGOALS 的值 不等于 clean.

3,strip函数的功能是取掉字符串开头和结尾的空格, $(stip ni hao ) 示例以" ni hao "作参数时其返回值是"ni hao".

注意: makefile和shell类似,变量类型只有一种,那就是字符串类型,即使你这样定义 INT = 123, INT分别编译每个c文件,然后将编译好的.o文件连接在一起即可,多看看帮助。 也会被当作"123"字符串来处理。

为什么有些人写makefile时要 CC=gcc ?直接用gcc写不就好了吗?

Complier and liner flags in CS 225

makefile有个默认的编译使用CC变量,而这个本来一开始是cc而不是gcc,所以需要指定。

当你需要更换编译器的时候是改一个变量容易还是改整个Makefile里出现的gcc容易

方便手动编译换CSRCS = $(wildcard ./.c ./../../base/log.c ./../../base/corsslib.c ./../../base/idmgr.c ./../../base/pool.c)编译器,好移植

方便将来换编译器

CC 是变量好不好,对你无语了

CC 是变量好不好,对你无语了

怎么在ubuntu在编辑makefile文件

当我们写的程序文件比较少的时候,敲入gcc

/g++,当你在大型工程中,在一个个编译文件的话,你可能就会很郁闷。linux有一个自带的make命令,它让你的工作省去了很大的力气,但是你要学习如何编写makefile文件。

方便其他平台,例如Windows下的VS编译器就是cl

makefile是一种特殊的文件格式,他将会帮你自动管理你的项目,很强大。

plaincopyprint?

#include "functions.h"

int main()

{print_hello();

cout << "The factorial of 5 is " << factorial(5) << endl;

return 0;

}///hello.cpp

#include "functions.h"

void print_hello()

}///factorial.cpp

#include "functions.h"

int factorial(int n)

{if(n!=1)

{ return(n factorial(n-1)); }

else return 1;

}//functions.h

void

print_hello();

int factorial(int n);

#include "functions.h"

int main()

{print_hello();

cout << "The factorial of 5 is " << factorial(5) << endl;

return 0;

}///hello.cpp

#include "functions.h"

void print_hello()

}///factorial.cpp

#include "functions.h"

int factorial(int n)

{if(n!=1)

{ return(n factorial(n-1)); }

else return 1;

}//functions.h

void

print_hello();

int factorial(int n);

请将以上文件放到一个目录下。

请注意: 我用的是g++进行编译的,你也可以按照你自己的选择来编译程序

make的作用

如果你运行: make命令,

它将会自动的在你的目录下寻找makefile文件,然后执行它,如果你几个makefile文件,你可以指定某一个特定的makefile文件

使用如下命令:

如果你想知道更多的make 用法,可以执行man make 命令

执的话就会出错,告诉我们undefined reference of dog::bark()行过程

编译器将会编译你的源文件,然后输出目标文件

链接器执行目标文件然后创建一个可执行文件。

最不理想的一种执行方式就是

g++ main.cpp hello.cpp factorial.cpp -o hello

makefile的基本规则是有以下构成:

target: dependencies

[tab] command

利用以上语法编写如下

all:

g++main.cpp hello.cpp factorial.cpp -o hello

然后运行你的makefile,如下

make -f Makefile-1

如上代码叙述,所写的目标是all,all是makefile默认的目标,如果没有其他规定,make语法将要执行这个目标文件。

我们还发现,all 目标并没有依赖的,所以按照命令让他安全的执行。

,make 通过 我们给的命令进行编译程序

使用依赖

这是因为,如果你修改一个单独的文件在你的项目,你不必重新编译一切,只有你修改。 请看下边的例子

[plain] view

plaincopyprint?

all: hello

hello: main.o factorial.o hello.o

factorial.o: factorial.cpp

g++ -c factorial.cpp

hello.o: hello.cpp

g++ -c hello.cpp

rm -rf o hello

all: hello

hello: main.o factorial.o hello.o

factorial.o: factorial.cpp

g++ -c factorial.cpp

hello.o: hello.cpp

g++ -c hello.cpp

rm -rf o hello

我们看到目标all

只有依赖,没有系统命令。为了去执行正确,它必须满足所有的目标所依赖的。目标都回去搜索所有的依赖,然后去执行它。

在例子中,我们看到了clean的目标,clean 这个目标就是清楚中间生成的.o文件和那些可执行文件

使用变量和注释

当你写makefil文件的时候,当你想改变一些编译的一些选项的时候,他是非常有用处的。

[plain] view

plaincopyprint?

CC=g++

# CFLAGS 是选项

CFLAGS=-c -Wall

# 目标文件

OBJECTS=main.o factorial.o hello.o

all: hello

hello: $(OBJECTS)

$(CC) main.o factorial.o hello.o -o hello

$(CC) $(CFLAGS) main.cpp

factorial.o: factorial.cpp

$(CC) $(CFLAGS) factorial.cpp

hello.o: hello.cpp

$(CC) $(CFLAGS) hello.cpp

rm -rf o hello

CC=g++

# CFLAGS 是选项

CFLAGS=-c -Wall

# 目标文件

OBJECTS=main.o factorial.o hello.o

all: hello

hello: $(OBJECTS)

$(CC) main.o factorial.o hello.o -o hello

$(CC) $(CFLAGS) main.cpp

factorial.o: factorial.cpp

$(CC) $(CFLAGS) factorial.cpp

hello.o: hello.cpp

$(CC) $(CFLAGS) hello.cpp

rm -rf o hello

你可以看到,使用这些有时候是非常有用的。你可以使用它们,赋值,当你想改变一些变量值的时候,然后你可以使用$(var),

来应用这些变量

如何继续下去

,你可以通过一些make的文档来写。

[plain] view

plaincopyprint?

CC=g++

CFLAGS=-c -Wall

SOURCES=main.cpp hello.cpp factorial.cpp

OBJECTS=$(SOURCES:.cpp=.o)

EXECUTABLE=hello

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)

$(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:

$(CC) $(CFLAGS) {1}lt; -o $@

CC=g++

CFLAGS=-c -Wall

SOURCES=main.cpp hello.cpp factorial.cpp

OBJECTS=$(SOURCES:.cpp=.o)

EXECUTABLE=hello

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)

$(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:

$(CC) $(CFLAGS) {1}lt; -o $@

,你可以通过一些make的文档来写。

在linux系统应用make命令时,makefile 与makefile有何区别

easy, 不过一行一行的比较麻烦:

分析linux

[cpp] view

make命令与Makefile的区别:

1、make命令有一些内置的默认功能,但是光有这个还是不知道怎么build程序。必须提供一个文件告诉make应用程序的构造,这个文件就是makefile。

2、Make和makefile提供了强大的功能来管理项目的编译以及发布install到指定文件夹。

3、make的原理是执行一个叫Makefile文件里的指令,make的基本用处是自动根据makefile里的指令来编译源文件。还可以用来做比如安装软件,卸载软件等事情,但前提是在makefile里写了。

4、比如makefile里有这么些内容:

install

:<

commands

>然后用make

install的话,make程序就会按照上面install:后面的指令<

commands

>执行安装,uninstall也是一样的道理,大部分的作者会写有卸载的部分,这时只要简单地执行make

install中的步骤,把什么文件拷到哪去了,然后分别手动删除。还有关键的一点是,编译安装完成后,不要删除源代码,不然就算作者写了unnistall目标,也没有makefile可以执行了下面通过实例一步步讲解如何使用makefile。下面的四段代码。。

linux 怎么自动生成makefile

cout << endl;

你应该先了解 makefile是什么; makefile可以自己写; makefile也可能是自动生成的,生成makefile所用到的工具为cmake. 以上CPP = g++不明白的概念请自行学习。

{cout << "Hello World!";

如何 编译 c code mikefile

clean:

Makefile 介绍

make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。

首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:

1. 如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。

2. 如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。

3. 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。

在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。 target ... : prerequisites ...

command

...

...

File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。

prerequisites就是,要生成那个target所需要的文件或是目标。

command也就是make需要执行的命令。(任意的Shell命令)

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于

prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。呵呵。还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。内容还多着呢。:)

1.2 一个示例

正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。

edit : main.o kbd.o command.o display.o \

insert.o seamain.o: main.cpprch.o files.o utils.o

cc -o edit main.o kbd.o command.o display.o \

insert.o search.o files.o utils.o

main.o : main.c defs.h

cc -c main.c

kbd.o : kbd.c defs.h command.h

cc -c kbd.c

command.o : command.c defs.h command.h

cc -c command.c

display.o : display.c defs.h buffer.h

cc -c display.c

insert.o : insert.c defs.h buffer.h

cc -c insert.c

search.o : search.c defs.h buffer.h

cc -c search.c

files.o : files.c defs.h buffer.h command.h

cc -c files.c

utils.o : utils.c defs.h

cc -c utils.c

clean :

rm edit main.o kbd.o command.o display.o \

insert.o search.o files.o utils.o

反斜杠(\)是换行符的意思。这样比较便于Makefile的易读。我们可以把这个内容保存在文件为“Makefile”或“makefile”的文件中,然后在该目录下直接输入命令“make”就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make

在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件(.o),依赖文件(prerequisites)就是冒号后面的那些

.c 文件和 .h文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit

的依赖文件。依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。

在定义好依赖关系后,后续的那一行定义了如何生成目标文件的作系统命令,一定要以一个Tab键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。

这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动##执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。

1.3 make是如何工作的

在默认的方式下,也就是我们只输入make命令。那么,

1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

2. 如果找到,它会找文件中的个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。

3. 如果edit文件不存在,或是edit所依赖的后面的 .o

文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。

4.

如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)

5. 当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件声明make的任务,也就是执行文件edit了。

这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出个目标文件。在找寻的过程中,如果出现错误,比如被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。

.cpp 和 .c 文件混合makefile 如何编写

其实你直接百度就行,很多例子。

## c.cpp混合编译的makefile模板

BIN = foyerserver.exe

CC = gcc

#这里只加入库头文件路径及库路径

INCS =

LIBS =

SUBDIRS =

#生成依赖信息时的搜索目录,比如到下列目录中搜索一个依赖文件(比如.h文件)

DEFINC = -I"./../../base/" -I"./../common" -I"./../../lib/lxnet/" -I"./../../lib/tinyxml/src/"

#给INCS加上依赖搜索路径,分开写可能会产生不一致情况,而且繁琐

#maintest.c tree/rbtree.c 多了子目录,那就直接添加 目录/.c即可 所有的源文件-- .c文件列表

#所有的.o文件列表

COBJS := $(CSRCS:.c=.o)

CPPOBJS := $(CPPSRCS:.cpp=.o)

##生成依赖信息 -MM是只生成自己的头文件信息,-M 包含了标准库头文件信息。

#-MT 或 -MQ都可以改变生成的依赖 xxx.o:src/xxx.h 为 src/xxx.o:src/xxx.h 当然。前面的 src/xxx.o需自己指定

#格式为 -MM 输入.c或.cpp 查找依赖路径 -MT或-MQ 生成规则,比如src/xxx.o

MAKEDEPEND = gcc -MM -MT

CFLAGS =

#CFLAGS += -Wall -ansi -DWIN32 -DNDEBUG -O2

CPPFLAGS =

#CPPFLAGS += -Wall -DWIN32 -DNDEBUG -O2

#-g 生成调试信息

#-ped# 这是注释,CC 编译器.antic参数与-ansi一起使用 会自动拒绝编译非ANSI程序

#-fomit-frame-pointer 去除函数框架

#-Wmissing-prototypes -Wstrict-prototypes 检查函数原型

#针对每个.c文件的.d依赖文件列表

CDEF = $(CSRCS:.c=.d)

CPPDEF = $(CPPSRCS:.cpp=.d)

PLATS = win32-debug win32-release linux-debug linux-release

none:

@echo " $(PLATS)"

win32-debug:

$(MAKE) all INCS=-I"c:/mingw/include" LIBS="-L"c:/mingw/lib" -L"./../../lib/lxnet" -llxnet -lws2_32 -L"./../../lib/tinyxml" -ltinyxml" CFLAGS="-Wall -DWIN32 -DDEBUG -g" CPPFLAGS="-Wall -DWIN32 -DDEBUG -g"

win32-release:

$(MAKE) all INCS=-I"c:/mingw/include" LIBS="-L"c:/mingw/lib" -L"./../../lib/lxnet" -llxnet -lws2_32 -L"./../../lib/tinyxml" -ltinyxml" CFLAGS="-Wall -DWIN32 -DNDEBUG -O2" CPPFLAGS="-Wall -DWIN32 -DNDEBUG -O2"

linux-debug:

$(MAKE) all INCS=-I"/usr/include" LIBS="-L"/usr/lib" -L"./../../lib/lxnet" -llxnet -lpthread -L"./../../lib/tinyxml" -ltinyxml" CFLAGS="-Wall -DDEBUG -g" CPPFLAGS="-Wall -DDEBUG -g"

linux-release:

$(MAKE) all INCS=-I"/usr/include" LIBS="-L"/usr/lib" -L"./../../lib/lxnet" -llxnet -lpthread -L"./../../lib/tinyxml" -ltinyxml" CFLAGS="-Wall -DNDEBUG -O2" CPPFLAGS="-Wall -DNDEBUG -O2"

all:$(BIN)

#生成.o的对自己目录中.h .c的依赖信息.d文件到.c所在的路径中

#$(DEF)文件是.d文件名列表(含目录),比如tree.d 匹配成功那么%就是tree,然后在尝试%.c,如果成功。则执行规则

hello : hello_world.cpp# $(<:.c=.o)是获取此.c文件的名字(含路径),然后变为.o比如 src/xxx.o。 以形成如下

# src/xxx.o : src/xxx.c .h .h 最前面!!注意。

# 此做法是每个.d都和生成他的.c在一个目录里,所以需要这样做。

# $(<:.c=.o)之类的 。此时的<相当于变量$< 。切记

# : : : 含义同下

$(CDEF) : %.d : %.c

$(MAKEDEPEND) $(<:.c=.o) $< $(DEFINC) > $@

$(CPPDEF) : %.d : %.cpp

$(MAKEDEPEND) $(<:.cpp=.o) $< $(DEFINC) > $@

#先删除依赖信息

#重新生成依赖信息

#这里出现了一个 $(MAKE) 没有定义的变量。这个变量是由 Make 自己定义的,它的值即为自己的位置,方便 Make 递归调用自己。

depend:

-rm $(CDEF)

-rm $(CPPDEF)

$(MAKE) $(CDEF)

$(MAKE) $(CPPDEF)

#$(OBJS):%.o :%.c 先用$(OBJS)中的一项,比如foo.o: %.o : %.c 含义为:试着用%.o匹配foo.o。如果成功%就等于foo。如果不成功,

# Make就会,然后。给foo.o添加依赖文件foo.c(用foo替换了%.c里的%)

# 也可以不要下面的这个生成规则,因为下面的 include $(DEF) 就隐含了。此处为了明了,易懂。故留着

$(COBJS)make -f mymakefile : %.o: %.c

$(CC) -c $< -o $@ $(INCS) $(DEFINC) $(CFLAGS)

$(CPPOBJS) : %.o: %.cpp

$(CPP) -c $< -o $@ $(INCS) $(DEFINC) $(CPPFLAGS)

# $@--目标文件,$^--所有的依赖文件,$<--个依赖文件。每次$< $@ 代表的值就是列表中的

$(CPP) -o $(BIN) $(COBJS) $(CPPOBJS) $(LIBS)

#引入了.o文件对.c和.h的依赖情况。以后.h被修改也会重新生成,可看看.d文件内容即知道为何

#引入了依赖就相当于引入了一系列的规则,因为依赖内容例如: 目录/xxx.o:目录/xxx.c 目录/xxx.h 也相当于隐含的引入了生成规则

#故上面不能在出现如: $(OBJS) : $(DEF)之类。切记

#include $(CDEF) $(CPPDEF)

.PHONY:clean clel

#清除所有目标文件以及生成的最终目标文件

-rm $(BIN) $(COBJS) $(CPPOBJS)

#rm .d

clel:

-rm $(BIN) $(COBJS) $(CPPOBJS)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 12345678@qq.com 举报,一经查实,本站将立刻删除。

联系我们

工作日:9:30-18:30,节假日休息