本文目的旨在介绍fvcom编译的全过程,顺便介绍linux中make命令的文件写法和一般的编程过程简述一下。

1.编程过程

编程,一般就是编写可执行程序过程。这个过程主要是源文件生成中间代码文件,再到可执行文件的两步过程:

1.1.源文件

即我们编写好的源程序,为文本文件。这代表着写文件时候可以非常随意,我们可以直接打开一个txt文件,然后直接编写程序,编写好的源程序(文件后缀改成相应源程序后缀即可)与用编程IDE软件写好的程序无异。我们习惯用IDE的原因,只不过是可以用些现成弹出来的代码段,或者是关键字提示这些特殊功能而已。也就是说,IDE是个比较人性化的文本编辑器。

1.2.中间代码文件

写好源程序后,编译器首先将源文件进行编译。

这个过程只是对源文件是否有语法错误,函数及变量是否声明正确进行判断。源程序全部正确的话,就把它专为机器码的二进制文件,linux中文件后缀为".o"。

1.3.可执行文件

全部的源程序转为".o"文件后,编译器将中间代码全部链接起来,生成可执行文件。

链接过程是链接函数和全局变量,错误时提示为链接错误(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File。

2.linux的make命令

window系统下有很多IDE直接为你做了编译、链接的工作,在linux中,make命令也是用来干这种活的。

对于一个大型工程项目,需要编译的文件不计其数,而且可能需要哪些文件需要
先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,make命令带来的好处就是——"自动化编译",一旦写好,只需要一个命令,整个工程完全自动编译,极大的提高了软件开发的效率。

2.1.makefile原则

make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接。我们用三个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有2个C文件,和1个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的目的是:

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

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

2.2.显式规则

我们再来看下makefile文件的显式规则:

target ... : prerequisites ...
command
......
  • target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。
  • prerequisites就是,要生成那个target所需要的文件或是目标。
  • command也就是make需要执行的命令。(任意的Shell命令)

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

例一:

#helloworld依赖file1.o、file2.o文件
#链接生成helloworld可执行文件
helloworld: file1.o file2.o
gcc file1.o file2.o -o helloworld #file1.o文件依赖file1.c、file1.h文件
#编译生成file1.o中间代码文件
file1.o: file1.c file1.h
gcc –c file1.c -o file1.o #file2.o文件依赖file2.c、file1.h文件
#编译生成file2.o中间代码文件
file2.0: file2.c file1.h
gcc -c file2.c -o file2.o

文件的执行过程如下:

首先识别出helloworld是首个目标文件,依赖file1.o file2.o两个中间代码文件;然后查看file1.o file2.o,寻找它们为target的两栏:查看file1.o,file2.o所依赖的文件,若其中任何一个新于target,则执行下面command那行命令,对应的target重新编译;最后,若file1.o file2.o其中任何一个新于helloworld,则执行helloworld下面的command命令,重新连接生成helloworld文件。

其实整个文件真正的target只有helloworld一个,假如目录中file1.o和file2.0都存在,且并不新于target,那么什么也不会执行。(真的么?)

例二:进阶:使用变量

OBJS = file1.o file2.o          这里OBJS是字符变量
CC = gcc CC、CFLAGS同理
CFLAGS = -Wall –O –g
helloworld : $(OBJS) $(OBJS)代表取出变量OBJS的内容,即file1.o file2.o
$(CC) $(OBJS) -o helloworld $(CC)、$(CFLAGS)同理
file1.o : file1.c file1.h
$(CC) $( CFLAGS) -c file1.c -o file1.o
file2.o : file2.c file1.h
$(CC) $( CFLAGS) -c file2.c -o file2.o

其实,我们将变量内容展开后,和例一中makefile文件内容无异。

前面生成文件的方法为依赖原则,即目标文件依赖某些文件,然后再根据这些依赖文件,依次生成目标文件。

还有一个规则是隐含规则,其中的后缀规则重点介绍下。

"隐含规则"也就是一种惯例,make会按照这种"惯例"心照不喧地来运行,那怕我们的Makefile中没有书写这样的规则。例如,把[.c]文件编译成[.o]文件这一规则,你根本就不用写出来,make会自动推导出这种规则,并生成我们需要的[.o]文件。

"隐含规则"又有"模式规则"和"后缀规则"两种,使用 "后缀规则"可以有效的保证我们Makefile的兼容性。

2.3.后缀规则

后缀规则:目标文件的后缀和依赖目标的后缀

若需要把所有的后缀为".c"的文件编译成中间代码".o"文件,命令格式为:

.c.o:
$(CC) -c $(CFLAGS) $(INCS) $*.c

第一行类似我们的依赖规则,相当于 : %o:%c.
(这里 % 代表任意个数的字符,%.c即所有的.c文件;%.o 的表示把所有后缀为.c文件名(%),后缀加上.o,作为生成的中间代码文件名。)

那么去除 % 后含义就是:

name1.o : name1.c
$(CC) -c $(CFLAGS) $(INCS) $ name1.c name2.o : name2.c
$(CC) -c $(CFLAGS) $(INCS) $ name2.c
name3.o : name3.c
$(CC) -c $(CFLAGS) $(INCS) $ name3.c
……
……

这里command行里 *.c 就代表后缀为 .c 的依赖文件

隐含规则的妙处就是,仅需短短两行;代替了大片的重复命令。

还有一个问题,那就是make命令不能识别所有种类的后缀,仅能识别其中一部分。令它识别一种特定后缀时候,我们需要修改.SUFFIXES变量的值:

.SUFFIXES = .o .f90 .F .F90

.SUFFIXES是makefile中一种特殊变量(所以是以"."开头的),专门储存可以识别的特定后缀种类。

3.fvcom的makefile

经过前两部分的铺垫,终于讲到中心了:我们的fvcom是怎样编译的?

下面贴出fvcom的makefile内容。(这应该没有什么侵权问题吧,喂?)

FVCOM编译过程详解的更多相关文章

  1. Android编译过程详解(一)

    Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...

  2. cegui-0.8.2编译过程详解

    cegui 编译过程详解(cegui-0.8.2) cegui配置整了好长时间了,在一位大牛帮助下终于搞定了,网上的教程大多是老版本的,cegui-0.8.2版的配置寥寥无几,现在总结一下,献给正在纠 ...

  3. GCC 概述:C 语言编译过程详解

    Tags: C Description: 关于 GCC 的个人笔记 GCC 概述 对于 GCC 6.1 以及之后的版本,默认使用的 C++ 标准是 C++ 14:使用 -std=c++11 来指定使用 ...

  4. uboot主Makefile分析(t配置和编译过程详解)

    1.编译uboot前需要三次make make distcleanmake x210_sd_configmake -j4 make distclean为清楚dist文件. make x210_sd_c ...

  5. uboot配置和编译过程详解【转】

    本文转载自:http://blog.csdn.net/czg13548930186/article/details/53434566 uboot主Makefile分析1 1.uboot version ...

  6. uboot配置和编译过程详解

    根据朱有鹏老师讲解整理 一.uboot主Makefile分析 1.uboot version确定(Makefile的24-29行) include/version_autogenerated.h文件是 ...

  7. C语言编译过程详解

    前言 C语言程序从源代码到二进制行程序都经历了那些过程?本文以Linux下C语言的编译过程为例,讲解C语言程序的编译过程. 编写hello world C程序: // hello.c #include ...

  8. Android编译过程详解(三)

    前面两节讲解了自定义Android编译项和创建Product产品配置文件,除了编译和定义产品相关环境变量外,还需要定义Board相关环境变量. 1. build/core/config.mk 109 ...

  9. gcc 编译过程详解-(转自CarpenterLee)

    前言 C语言程序从源代码到二进制行程序都经历了那些过程?本文以Linux下C语言的编译过程为例,讲解C语言程序的编译过程. 编写hello world C程序: // hello.c #include ...

随机推荐

  1. 【UE4 C++】UKismetSystemLibrary 源代码

    // Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" # ...

  2. 2021北航敏捷软工Beta阶段评分与总结

    概述 Beta 阶段评分,按照之前的规则,主要组成部分为: 博客部分,基于 Beta 阶段博客的评分(每篇正规博客 10 分,每篇 Scrum5 分,评定方式类比往年) 评审部分,基于 Beta 阶段 ...

  3. seata整合nacos完成分布式的部署

    seata整合nacos完成分布式的部署 一.背景 二.部署机器 三.部署步骤 1.在seata上创建命名空间 2.下载对应版本的seata 3.单机启动 1.修改seata配置文件 1.修改注册中心 ...

  4. FreeRTOS学习笔记——FreeRTOS 任务基础知识

    RTOS 系统的核心就是任务管理,FreeRTOS 也不例外,而且大多数学习RTOS 系统的工程师或者学生主要就是为了使用RTOS 的多任务处理功能,初步上手RTOS 系统首先必须掌握的也是任务的创建 ...

  5. python3.5 安装mysqlclient

    python 3.5 安装 mysqlclient 会失败 pip install mysqlclient 注意这里环境中只有python3.5 会出现一大堆红字 编译终止, error: comma ...

  6. POJ 2446 Chessboard(二分图最大匹配)

    题意: M*N的棋盘,规定其中有K个格子不能放任何东西.(即不能被覆盖) 每一张牌的形状都是1*2,问这个棋盘能否被牌完全覆盖(K个格子除外) 思路: M.N很小,把每一个可以覆盖的格子都离散成一个个 ...

  7. vivo 全球商城:商品系统架构设计与实践

    一.前言 随着用户量级的快速增长,vivo官方商城v1.0的单体架构逐渐暴露出弊端:模块愈发臃肿.开发效率低下.性能出现瓶颈.系统维护困难. 从2017年开始启动的v2.0架构升级,基于业务模块进行垂 ...

  8. Mysql教程:(三)运算符:数学运算符

    运算符:数学运算符 mysql> select class,number,maths,maths+5 from score; mysql>select class,number,chine ...

  9. python3+Robotframework+ride+Selenium2Library+Autoitlibrary环境搭建

    1.安装python3.8 第一步是安装Python:https://www.python.org/,RF框架是基于python 的,所以一定要有python环境.将python-3.8.2-amd6 ...

  10. Vuex状态管理——任意组件间通信

    核心概念 在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信. 每一个 Vuex 应用的 ...