基础知识(三)makefile文件编写初级篇
2016-10-17 21:21
411 查看
Linux下进行c++开发,需要熟悉相关编译器的编译、链接命令。这边主要以实例讲解,如何在linux中,进行c++程序简单的编译链接运行。
一、单文件编译链接
这里先从最简单的单个文件编译链接为例。在桌面下新建一个名字为:helloworld.cpp
文件内容:
[c++] view
plain copy
#include <iostream>
int main(int argc,char *argv[])
{
std::cout << "hello, world" << std::endl;
return(0);
}</iostream>
直接cd文件所在的目录,然后输入命令:g++ helloworld.cpp 将生成可执行文件,名字为a.out的直接生成可执行文件。如果要指定输出的可执行文件名,那么命令为:g++ helloworld.cpp -o file_name 此时将生成文件名为:file_name.out 的可执行文件 ,即 可选项 -o 用于指定文件生成的名字。在大多数系统中GCC安装是会安装一个名为c++的程序,也就是说此时命令:c++ 与g++是相同的,因此也可以使用命令:c++ helloworld.cpp -o file_name
编译上面的文件。.h文件不需要指定编译,因为程序编译中,会自动根据#include 进行搜索当前目录、系统目录。
总结:如果只有一个.cpp文件的,且里面包含main函数,那么直接用:g++命令,将直接生成可执行文件。
二、多文件链接编译链接
多文件的编译链接需要包含两个步骤:1、编译,用可选命令 -c 进行编译cpp文件,生成.o文件 2、链接,根据步骤1生成的.o文件生成可执行文件 。看一下以下实例:
建立头文件名:speak.h 内容如下:
[c++] view
plain copy
#include <iostream>
class Speak
{
public:
void sayHello(const char *);
};</iostream>
建立源文件:speak.cpp ,内容如下:
[c++] view
plain copy
#include "speak.h"
void Speak::sayHello(const char *str)
{
std::cout << "Hello " << str << "\n";
}
主函数文件: hellospeak.cpp 调用speak类
[c++] view
plain copy
/* hellospeak.cpp */
#include "speak.h"
int main(int argc,char *argv[])
{
Speak speak;
speak.sayHello("world");
return(0);
}
现在有两个.cpp文件,其中一个包含有main函数,那么就不能一步直接生成可执行文件,这时要分为两个步骤才能生成可执行文件。采用-c命令,先进行编译,生成.o文件,然后再生成可执行文件,命令如下:
g++ -c filename1.cpp main.cpp
g++ filename1.o main.o -o out_filename
或者采用如下两个命令:
g++ -c filename1.cpp
g++ filename1.o main.cpp -o out_filename
三、makefile文件编写
以上2个文件编译链接,用简单的命令就可以实现,然而我们遇到的项目,往往是几十个,甚至几百几千个文件的,那么这个时候通过简单的命令编译链接的方法,就会相当复杂,这个时候我们就要用到make了。
makefile文件编写规则:
target1 : prerequisites1
command1
target2 : prerequisites2
command
……
目标:依赖
执行指令 ...
(1)target目标,我们要生成的文件。
(2) prerequisites依赖,就是要生成那个target所需要的文件或是目标。
(3) command命令 ,相关的生成target所需要的编译链接命令。(g++)
make执行的时候,可以根据文件是否更新,进行编译链接。这个就像vs里面,当我们有一个文件被改动的时候,这个文件及其相关的链接文件将被重新编译链接。如果没有更新,则vs不会对这个文件进行重新编译,这样可以减少每次都重复编译,提高效率。makefile这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行(command一定要以Tab键开始,否者编译器无法识别command),减少重复编译,提高了其软件工程管理效率。
为了简便起见,我们这边继续以上面的例子为试验,进行学习makefile文件的编写。
新建文件名:makefile ,文件内容:
[c++] view
plain copy
outfile : speak.o helloworld.o
g++ speak.o helloworld.o -o outfile
speak.o : speak.cpp speak.h
g++ -c speak.cpp -o speak.o
helloworld.o : helloworld.cpp speak.h
g++ -c helloworld.cpp -o helloworld.o
然后在终端直接输出命令:make 即可完成编译链接,同时将生成可执行文件名:outfile
编写注意事项:
1、makefile文件中,命令的换行要用 \ ,这个与matlab用...换行有点类似 \
否则会出现如下错误:
![](https://img-blog.csdn.net/20150507225254171?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGppbWNl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
正确的写法应该是这样的:
[c++] view
plain copy
bj=speak.o \
helloworld.o
outfile:$(obj)
g++ $(obj) \
-o outfile
helloworld.o speak.o:speak.h
2、makefile的命令g++前面一定要是tab按键,其它的都不行 即便是空格也会报错
上面简简单单的两个文件编译,就需要些那么多代码,是不是感觉很不爽,接着我们讲一下如何简化:
1、定义变量,以此简化命令,在以上的makefile文件中我们知道,“speak.o helloworld.o”这一段被重复使用了两次,因此以上的makefile我们也可以这样写:
[c++] view
plain copy
obj=speak.o helloworld.o
outfile : $(obj)
g++ $(obj) -o outfile
speak.o : speak.cpp speak.h
g++ -c speak.cpp -o speak.o
helloworld.o : helloworld.cpp speak.h
g++ -c helloworld.cpp -o helloworld.o
我们定义了变量名obj,使其值为“speak.o helloworld.o” ,然后在后面,只要有 “speak.o helloworld.o”,我们就用变量$(obj)替换掉。这样就做了第一步,makefile文件的简化,在终端输入make,依然可以生成同样的可执行文件。
2、使用自动推导,简化命令。只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么 whatever.cpp,就会默认为whatever.o的依赖文件。并且 g++ -c whatever.cpp也会被自动推导出来,那么以上的命令我们又可以继续简化为:
[c++] view
plain copy
obj=speak.o helloworld.o
outfile : $(obj)
g++ $(obj) -o outfile
speak.o : speak.h
helloworld.o : speak.h
也就是说如果目标文件是生成.o文件,那么我们可以不必包含 编译命令,及其相应的源文件,只留下其编译所需要的头文件。
3、因为helloworld.o speak.o两个文件都包含同样的一个头文件,当然你也可以这样写:
[c++] view
plain copy
obj=speak.o helloworld.o
outfile : $(obj)
g++ $(obj) -o outfile
helloworld.o speak.o : speak.h
![](http://static.blog.csdn.net/images/save_snippets.png)
不过这种写法不推荐,很容易混乱掉。
初级部分先讲到这里,后面我会继续讲比较深入的makefile文件编写。本文地址:http://blog.csdn.net/hjimce/article/details/45567689
作者:hjimce 联系qq:1393852684 更多资源请关注我的博客:http://blog.csdn.net/hjimce
原创文章,版权所有,转载请保留本行信息
Cmake学习:http://hahack.com/codes/cmake/
一、单文件编译链接
这里先从最简单的单个文件编译链接为例。在桌面下新建一个名字为:helloworld.cpp
文件内容:
[c++] view
plain copy
#include <iostream>
int main(int argc,char *argv[])
{
std::cout << "hello, world" << std::endl;
return(0);
}</iostream>
直接cd文件所在的目录,然后输入命令:g++ helloworld.cpp 将生成可执行文件,名字为a.out的直接生成可执行文件。如果要指定输出的可执行文件名,那么命令为:g++ helloworld.cpp -o file_name 此时将生成文件名为:file_name.out 的可执行文件 ,即 可选项 -o 用于指定文件生成的名字。在大多数系统中GCC安装是会安装一个名为c++的程序,也就是说此时命令:c++ 与g++是相同的,因此也可以使用命令:c++ helloworld.cpp -o file_name
编译上面的文件。.h文件不需要指定编译,因为程序编译中,会自动根据#include 进行搜索当前目录、系统目录。
总结:如果只有一个.cpp文件的,且里面包含main函数,那么直接用:g++命令,将直接生成可执行文件。
二、多文件链接编译链接
多文件的编译链接需要包含两个步骤:1、编译,用可选命令 -c 进行编译cpp文件,生成.o文件 2、链接,根据步骤1生成的.o文件生成可执行文件 。看一下以下实例:
建立头文件名:speak.h 内容如下:
[c++] view
plain copy
#include <iostream>
class Speak
{
public:
void sayHello(const char *);
};</iostream>
建立源文件:speak.cpp ,内容如下:
[c++] view
plain copy
#include "speak.h"
void Speak::sayHello(const char *str)
{
std::cout << "Hello " << str << "\n";
}
主函数文件: hellospeak.cpp 调用speak类
[c++] view
plain copy
/* hellospeak.cpp */
#include "speak.h"
int main(int argc,char *argv[])
{
Speak speak;
speak.sayHello("world");
return(0);
}
现在有两个.cpp文件,其中一个包含有main函数,那么就不能一步直接生成可执行文件,这时要分为两个步骤才能生成可执行文件。采用-c命令,先进行编译,生成.o文件,然后再生成可执行文件,命令如下:
g++ -c filename1.cpp main.cpp
g++ filename1.o main.o -o out_filename
或者采用如下两个命令:
g++ -c filename1.cpp
g++ filename1.o main.cpp -o out_filename
三、makefile文件编写
以上2个文件编译链接,用简单的命令就可以实现,然而我们遇到的项目,往往是几十个,甚至几百几千个文件的,那么这个时候通过简单的命令编译链接的方法,就会相当复杂,这个时候我们就要用到make了。
makefile文件编写规则:
target1 : prerequisites1
command1
target2 : prerequisites2
command
……
目标:依赖
执行指令 ...
(1)target目标,我们要生成的文件。
(2) prerequisites依赖,就是要生成那个target所需要的文件或是目标。
(3) command命令 ,相关的生成target所需要的编译链接命令。(g++)
make执行的时候,可以根据文件是否更新,进行编译链接。这个就像vs里面,当我们有一个文件被改动的时候,这个文件及其相关的链接文件将被重新编译链接。如果没有更新,则vs不会对这个文件进行重新编译,这样可以减少每次都重复编译,提高效率。makefile这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行(command一定要以Tab键开始,否者编译器无法识别command),减少重复编译,提高了其软件工程管理效率。
为了简便起见,我们这边继续以上面的例子为试验,进行学习makefile文件的编写。
新建文件名:makefile ,文件内容:
[c++] view
plain copy
outfile : speak.o helloworld.o
g++ speak.o helloworld.o -o outfile
speak.o : speak.cpp speak.h
g++ -c speak.cpp -o speak.o
helloworld.o : helloworld.cpp speak.h
g++ -c helloworld.cpp -o helloworld.o
然后在终端直接输出命令:make 即可完成编译链接,同时将生成可执行文件名:outfile
编写注意事项:
1、makefile文件中,命令的换行要用 \ ,这个与matlab用...换行有点类似 \
否则会出现如下错误:
正确的写法应该是这样的:
[c++] view
plain copy
bj=speak.o \
helloworld.o
outfile:$(obj)
g++ $(obj) \
-o outfile
helloworld.o speak.o:speak.h
2、makefile的命令g++前面一定要是tab按键,其它的都不行 即便是空格也会报错
上面简简单单的两个文件编译,就需要些那么多代码,是不是感觉很不爽,接着我们讲一下如何简化:
1、定义变量,以此简化命令,在以上的makefile文件中我们知道,“speak.o helloworld.o”这一段被重复使用了两次,因此以上的makefile我们也可以这样写:
[c++] view
plain copy
obj=speak.o helloworld.o
outfile : $(obj)
g++ $(obj) -o outfile
speak.o : speak.cpp speak.h
g++ -c speak.cpp -o speak.o
helloworld.o : helloworld.cpp speak.h
g++ -c helloworld.cpp -o helloworld.o
我们定义了变量名obj,使其值为“speak.o helloworld.o” ,然后在后面,只要有 “speak.o helloworld.o”,我们就用变量$(obj)替换掉。这样就做了第一步,makefile文件的简化,在终端输入make,依然可以生成同样的可执行文件。
2、使用自动推导,简化命令。只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么 whatever.cpp,就会默认为whatever.o的依赖文件。并且 g++ -c whatever.cpp也会被自动推导出来,那么以上的命令我们又可以继续简化为:
[c++] view
plain copy
obj=speak.o helloworld.o
outfile : $(obj)
g++ $(obj) -o outfile
speak.o : speak.h
helloworld.o : speak.h
也就是说如果目标文件是生成.o文件,那么我们可以不必包含 编译命令,及其相应的源文件,只留下其编译所需要的头文件。
3、因为helloworld.o speak.o两个文件都包含同样的一个头文件,当然你也可以这样写:
[c++] view
plain copy
obj=speak.o helloworld.o
outfile : $(obj)
g++ $(obj) -o outfile
helloworld.o speak.o : speak.h
![](http://static.blog.csdn.net/images/save_snippets.png)
不过这种写法不推荐,很容易混乱掉。
初级部分先讲到这里,后面我会继续讲比较深入的makefile文件编写。本文地址:http://blog.csdn.net/hjimce/article/details/45567689
作者:hjimce 联系qq:1393852684 更多资源请关注我的博客:http://blog.csdn.net/hjimce
原创文章,版权所有,转载请保留本行信息
Cmake学习:http://hahack.com/codes/cmake/
相关文章推荐
- 基础知识(三)makefile文件编写初级篇
- Linux下C语言编程基础知识--gcc编译器的使用、MakeFile文件的编写
- Linux平台Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础篇
- Makefile文件的编写基础篇
- 【转贴】Linux平台Makefile文件的编写基础
- Linux平台Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础篇
- MEX 文件编写基础知识
- Unix/Linux 平台Makefile文件的基础编写
- Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础
- Linux平台Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础篇 (转载)
- Linux平台Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础篇
- Linux平台Makefile文件的编写基础篇