makefile相关(+elf)

最近需要阅读vim的源代码,但是好好的一个.c文件里满屏的#ifdef、#endif…….让我怀疑自己到底有没有学过C语言,百度了一下,有建议先学一下makefile,粗略了解一下。

makefile

好处是自动化编译

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

makefile里有什么?

  1. 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
  2. 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
  3. 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
  4. 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。
  5. 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“/#”。

makefile的书写规则:

? 1.如果这个工程没有编译过,那么所有c文件都要编译并被链接

? 2.如果这个工程的某几个c文件被修改,那么只需要编译被修改的c文件,并链接目标程序

? 3.如果这个工程的头文件被修改,那么需要编译引用了这几个头文件的c文件,并链接目标程序

makefile可以使我们只用一个make命令,就可以使其根据当前的文件修改情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。

make是如何工作的?(只输入make命令)

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

? 2.如果找到,它会找文件中的第一个目标文件(target),并把这个文件作为最终的目标文件

? 3.如果目标文件不存在,或是目标文件所依赖的后面的 .o文件的文件修改时间要比当前这个文件新,那么,他就会执行后面所定义的命令来生成当前这个目标文件

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

? 5.当然,C文件和头文件是存在的,于是make会生成 .o 文件, 然后再用 .o 文件生成make的终极任务,也就是执行目标文件了

? 以上就是整个make的依赖性,make会一层又一层地去找文件的依赖关系, 直到最终编译出第一个目标文件。如果没找到依赖文件,make就会报错退出。

如vim1.14中的规则:

amiga.o: amiga.c $(INCL) amiga.h cc $(CFLAGS) -hi$(INCL) amiga.c

amiga.o是目标,amiga.c和amiga.h是目标所依赖的源文件。如果amiga.c和amiga.h的文件日期比amiga.o文件日期要新,或是amiga.o不存在,那么依赖关系发生。

如果生成(或更新)amiga.o文件,也就是cc命令(C语言编译程序默认命令,CFLAGS为C语言编译器参数)说明了如何生成/更新

GNU的make工作时的执行步骤:

  1. 读入所有的makefile
  2. 读入被include的其它makefile
  3. 初始化文件中的变量
  4. 推导隐晦规则,并分析所有规则
  5. 为所有的目标文件创建依赖关系链
  6. 根据依赖关系,决定哪些目标要重新生成
  7. 执行生成命令

thanks to:

https://blog.csdn.net/haoel/article/details/2886

https://blog.csdn.net/weixin_38391755/article/details/80380786


条件编译

可以看出vim1.14的源程序中有许多#ifdef、#endif字段,这属于条件编译。源代码中的所有行都参加编译,但有时希望对其中一部分内容在其满足一定条件时才编译。

e.g. #ifdef AMIGA(标识符) void(程序段1) #else int(程序段2) #endif

即当标识符已经被定义过,则对程序段1进行编译,否则编译程序段2

#ifndef==if not defined:最主要的目的是防止头文件的重复包含和编译。检查预编译常量在前面是否已经被宏定义,如果没有被宏定义,则条件指示符#ifndef为真。

比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。

e.g. #ifndef x //如果没有定义x #define x //定义x #endif //结束如果

#undef取消前面由#define定义的预处理器标识符



read Vim1.14

amiga.c:

ArpBase

IsInteractive()//判断是否为交互窗口

quickfix mode:Quickfix模式的主要思想是保存一个位置列表,然后提供一系列命令,实现在这个位置列表中跳转。在vim启动编译,然后vim会根据编译器输出的错误信息,自动跳到第一个出错的地方,让你进行修改;修改完后,使用一个快捷键,跳到下一个错误处,再进行修改,方便的很。


ELF(executable and linkable format)

一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。

ELF文件由4部分组成:ELF header、程序头表、节、节头表

只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。

ELF文件格式主要有三种:

1)可重定向文件:文件保存着代码和适当的数据,用来和其他的目标文件一起来创建一个可执行文件或者是一个共享目标文件。(目标文件或者静态库文件,即linux通常后缀为.a和.o的文件)

2)可执行文件:文件保存着一个用来执行的程序。(例如bash,gcc等)

3)共享目标文件:共享库。文件保存着代码和合适的数据,用来被下连接编辑器和动态链接器链接。(linux下后缀为.so的文件。)

ELF header

在文件的开始,保存了路线图,描述了该文件的组织情况。(/usr/include/elf.h 可查看ELF的文件头)

ELF格式的定义

http://refspecs.linuxbase.org/elf/elf.pdf

原文地址:https://www.cnblogs.com/lyeeer/p/12143848.html

时间: 2024-10-17 02:47:36

makefile相关(+elf)的相关文章

Makefile相关知识

1. Makefile的编写: 1>. makefile的命名 1. makefile 2. Makefile 2>. makefile中的规则 三部分: 目标(app):依赖(main.c a.c b.c) 命令(gcc main.c a.c b.c -o app) gcc main.c a.c b.c -o app 执行 make 命令, 就会按照makefile中编写的规则编译整个项目 在makefile文件中可以有一个或多个规则 第一版本:  app:main.c sub.c mul.

Makefile心得

笔者擅长的语言是Java,最近被老师拉过来做Linux C,里面经常用到Makefile. Makefile大学的时候学过,当时觉得很头疼,放了几年后,现在看起来,没以前那么难了,大体思路和shell差不多,就是定义变量.拼接命令之类的,如果能很好的了解gcc的编译命令的话,写个Makefile真是不在话下(突然感觉这句话说的太肤浅....).这里简单记录一下写Makefile中发现的几点吧. gcc相关: 需要编译生成动态库的时候,需要在参数中添加-fPIC -shared标志位,然后再将各对

Linux内核配置、编译及Makefile简述

Hi,大家好!我是CrazyCatJack.最近在学习Linux内核的配置.编译及Makefile文件.今天总结一下学习成果,分享给大家^_^ 1.解压缩打补丁 首先是解压缩你获取到的Linux内核.这里我用到的是linux.2.22.6版本的内核.在Linux下命令行通过tar xjf linux.2.22.6.tar.bz2解压内核.然后,如果你需要对这个内核打补丁的话,用patch命令:patch -px <../linux.2.22.6.patch.这里的px指的是忽略掉补丁文件中描述的

从头开始写项目Makefile(零):前言

[版权声明:转载请保留出处:blog.csdn.net/gentleliu.Mail:shallnew at 163 dot com] 一不小心工作三年了,也就是写了三年代码了,码农生活过的真快.最近发现我们项目的Makefile不够好,于是着手改了一下,以前Makefile写好后就很少动它了,直接在项目之间拷来拷去直接拿来用,这次重新修改项目Makefile,发现自己又学到不少东西,于是乎决定总结一下记录下来与各位苦逼的程序猿一道分享一下. 其实各大论坛博客已经有很多关于Makefile的文章

Makefile入门

1.Makefile概述: 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂.这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义.特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力. 因为,makefile关

linux 静态库,makefile

mkdir testlib,组织文件目录如下 my_math.h int add(int a, int b); int subtract(int a, int b); my_math.c #include "../include/my_math.h" int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } my_print.h #include <stdio.h>

uboot移植之makefile分析

/* Name:uboot之makefile分析 Data:2015-3-3 Author:suj_un */ Uboot之makefile分析 编译uboot,内核或者其他软件只需要执行make命令就可以生成可执行文件.执行命令后是怎么工作的?要知道这个就要看makefile了.现在就来揭开这玩意神秘的面纱.其中会粘一些代码段来分析... VERSION = 2010 PATCHLEVEL = 03 SUBLEVEL = EXTRAVERSION = ifneq "$(SUBLEVEL)&qu

make 和 makefile(一)

从今天开始,我们来学习 makefile 了.那么什么是 make 呢?为什么需要 make 呢?在我们之前学习的 C 语言以及 C++ 语言中,我们在编译的时候只需要 gcc 或者 g++ 命令就可以完成源码的编译了.但是在嵌入式中一些大型的项目中,如内核的编译,动辄上万个源文件,我们还可能去一行一行的敲 gcc 命令吗?肯定不会了,这时我们便需要一个工具来进行代替了,此时便需要 makefile 了. 本系列博客内容是根据狄泰软件学院的<门徒计划>中的 makefile 相关内容总结而来,

Makefile之深入浅出

什么是 make 呢?为什么需要 make 呢?在我们之前学习的 C 语言以及 C++ 语言中,我们在编译的时候只需要 gcc 或者 g++ 命令就可以完成源码的编译了.但是在嵌入式中一些大型的项目中,如内核的编译,动辄上万个源文件,我们还可能去一行一行的敲 gcc 命令吗?肯定不会了,这时我们便需要一个工具来进行代替了,此时便需要 makefile 了. 本系列博客内容是根据狄泰软件学院的<门徒计划>中的 makefile 相关内容总结而来.其中包含了 Makefile 语言的各种基础知识点