一、使用传统程序语言进行编译的简单范例
1、单一程序:印出 Hello World
- 编辑程序码,亦即源代码
- 开始编译与测试执行
在默认的状态下,如果我们直接以 gcc 编译源代码,并且没有加上任何参数,则可执行文件 的文件名会被自动设置为 a.out 这个文件名称。
2、主、副程序链接:副程序的编译
- 进行程序的编译与链接 (Link)
产生目标文件的好处是,由于我们的源码文件有时并非只有一个文件,所以我们无法直接进行编译。这个时候就就需要先产生目标文件,然后再以连接制作成为 binary 可执行文件。
3、调用外部函数库:加入链接的函数库
- 编译时加入额外函数库链接的方式:
特别注意,使用 gcc 编译时所加入的那个 -lm 是有意义的,他可以拆开成两部份来看:
- -l :是“加入某个函数库(library)”的意思,
- m :则是 libm.so 这个函数库,其中, lib 与扩展名(.a 或 .so)不需要写
4、gcc 的简易用法 (编译、参数与链结)
- 仅将源代码编译成为目标文件,并不制作链接等功能:
会自动的产生 hello.o 这个文件,但是并不会产生 binary 可执行文件
- 在编译的时候,依据作业环境给予最优化执行速度
会自动的产生 hello.o 这个文件,并且进行最优化
- 在进行 binary file 制作时,将链接的函数库与相关的路径填入
这个指令较常下达在最终链接成 binary file 的时候,
-lm 指的是 libm.so 或 libm.a 这个函数库文件;
-L 后面接的路径是刚刚上面那个函数库的搜寻目录;
-I 后面接的是源代码内的 include 文件之所在的目录。
- 将变异的结果输出成某个特定文件名
-o 后面接的是奥输出的 binary file 文件名
- 在编译的时候,输出较多的讯息说明。
加入 -Wall 之后,程序的编译会变得较为严谨一点,suoyijinggaoxunxiyehuixianshichul。
二、用 make 进行宏编译
make 的功能是可以简化编译过程里面所下达的指令,同时还具有很多很方便的功能。
1、为什么要使用 make
假设我的可执行文件里面包含了多个个源代码文件,由于这 四个文件里面包含了相关性,并且还用到数学函数在里面,所以如果你想要让这个程序可以 跑, 那么就需要这样编译:
- 先进行目标文件的编译,最终会有四个 *.o 的文件名出现:
- 再进行链接成为可执行文件,并加入 libm 的数学函数,以产生 main 可执行文件:
- 本程序的执行结果,必须输入姓名、360 度角的角度值来计算:
编译的过程需要进行好多动作!而且如果要重新编译,则上述的流程得要重新来一遍。如果我们利用 make 工具的话只需要:
- 先编辑 makefile 这个规则档,内容只要作出 main 这个可执行文件
- 尝试使用 makefile 制订的规则进行编译的行为:
在不删除任何文件的情况下,重新执行一次编译的动作,只会进行更新 (update) 的动作而已。
简而言之,make 的好处如下:
- 简化编译时需要下达的指令;
- 若在完成编译之后,修改了某个源代码文件,则 make 仅会针对被修改了的文件进行编译,其他的 object file 不会被更动;
- 最后可以根据相依性来更新可执行文件。
2、makefile 常用的基本语法与变量
基本的 makefile 规则是这样的:
标签(target): 目标文件1 目标文件2
<tab> gcc -o 欲创建的可执行文件 目标文件1 目标文件2
那个标签(target) 就是我们想要创建的信息,而目标文件就是具有相关性的 object files , 那创建可执行文件的语法就是以按键开头的那一行!特别给他留意喔,“命令列必须要 以 tab 按键作为开头”才行!他的规则基本上是这样的:
- 在 makefile 当中的 # 代表注解;
- <tab> 需要在命令行 (例如 gcc 这个编译器指令) 的第一个字符;
- 标签 (target)与相依性文件(就是目标文件)之间需以 ":" 隔开。