- 博客(16)
- 收藏
- 关注
原创 快速搞懂 ”ld“ ——链接器
链接器的功能:将一个可执行程序所需的目标文件和库最终整合在一起。 一个程序包含三个段:.text 、.data 和 .bss 段。 而各目标文件和库都包含这三段,所以,ld 链接器的功能就是将各个目标文件和库的三段合并在一起。 当然,链接器所完成的链接工作并非只是简单地将各个目标文件和库的三段内存堆砌在一起,而是还要完成 “重定位” 的工作。
2016-07-22 13:33:05 10810 5
原创 字节序与边界对齐
字节序: 32位处理器每次处理 4 个字节。 当数据类型大于1个字节时,其在内存中的顺序存在两种模式: (1)小端:低字节放在低地址 (2)大端:低字节放在高地址边界对齐: 边界对齐是处理器为了提高处理性能而对存取数据的起始地址所提出的一种要求。
2016-07-22 13:30:22 830
原创 快速编写“专家级”makefile(4.打造更专业的编译环境——改善编译效率)
对于大型项目,提高项目的编译速度有着非常重要的意义。 从 Makefile 中看,一个可以改善编译效率的地方与其中的隐式规则有关 隐式规则即:make 自带的编译规则,如生成 .o 文件的规则 %.o : %.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $^ 而我们在前面
2016-07-22 13:28:06 301
原创 快速编写“专家级”makefile(4.打造更专业的编译环境——管理对库的依赖关系)
对于前面的 Makefile , 当我们改动了 foo.c 文件时,会导致 libfoo.a 库的重新编译,但并没有使得 huge.exe 重新编译。原因是:我们只是指定了 huge.exe 生成时所需的库,并没有让 huge.exe 依赖于这些库文件,所以库文件的改动并不能使得 huge.exe 被重新编译 解决:前面提出, LINK_LIBS 已经指明了 huge.exe 生
2016-07-22 13:27:11 470
原创 快速编写“专家级”makefile(4.打造更专业的编译环境——增强可使用性)
从前面看来,为了编译 huge 项目需要进入不同的目录运行 make ,我们可以简化它: huge / build / Makefile.PHONY : all cleanROOT = $(realpath ..)DIRS = $(ROOT)/code/foo/src\ $(ROOT)/code/bar/src\ $(ROOT)/code/huge/srcRM =
2016-07-22 13:26:23 638
原创 快速编写“专家级”makefile(4.打造更专业的编译环境——实现库链接)
根据前面所运行结果,main.o 被正确地生成了,但在链接时因为找不到 foo() 函数的实现而出现错误。由于 foo() 函数的实现是放在 libfoo.a 库中的,而 Makefile 中并没有告诉编译器在生成 huge.exe 时需要与 libfoo.a 库链接在一起 huge / build / make.rule.PHONY : all cleanNKDIR
2016-07-22 13:25:30 370
原创 快速编写“专家级”makefile(4.打造更专业的编译环境——支持头文件目录的指定)
现将项目文件放入各目录中:huge / code / foo / inc / foo.h#ifndef __FOO_H#define __FOO_Hvoid foo();#endifhuge / code / foo / inc / foo.c#include #include "foo.h"void foo(){ printf("This is foo
2016-07-22 13:24:32 429
原创 快速编写“专家级”makefile(4.打造更专业的编译环境——增进复用性)
可以将共用部分放入一个独立的文件中——这就是 build 目录下的 make.rule 文件的作用 那么,在 foo 模块的 Makefile 中,哪些是不能共用的呢?变量 EXE 和 LIB 的定义对于每一个软件模块是不同的DIR_EXES 变量和 DIR_LIBS 变量由于运用了相对路径,所以也是每个模块特有的。但是可以采用绝对路径的方式解决这个问题。比如,可以定
2016-07-22 13:22:57 483
原创 快速编写“专家级”makefile(4.打造更专业的编译环境)
前面的 simple 和 complicated 项目都是采用了单一的目录结构,但大型的项目往往用多个目录来存放不同的模块。下面我们通过 huge 项目来模拟一个更加专业的编译环境。 下图说明了 huge 项目将采用的目录结构 从图中:huge 最上层有两个目录: build 和 codebuild 目录用于存放个 Makefile 文件间的共享文件
2016-07-22 13:21:33 559
原创 快速编写“专家级”makefile(3.提高编译环境的实用性)
首先创建一个 complicated 项目:complicated / foo.h#ifndef __FOO_H#define __FOO_Hvoid foo();#endifcomplicated / foo.c#include #include "foo.h"void foo(){ printf("This is foo ()!\n");}
2016-07-21 18:00:30 934
原创 快速编写“专家级”makefile(2.创建基本编译环境-使用功能”函数“)
1.abspath 功能:将 _names 中的各路径名转换成绝对路径 形式:$(abspath _names) 返回值:返回转换结果实例:.PHONY: allROOT:= $(abspath/usr/.../lib)all:@echo $(ROOT) 运行结果$make/
2016-07-21 17:59:04 910
原创 快速编写“专家级”makefile(2.创建基本编译环境)
一、运用规则:先来创建 simple 项目的两个源程序:foo.c#include void foo(){ printf("This is foo ()!\n");}main.c#include extern void foo();int main(){ foo(); return 0;} 对于项目,在编写 Makefil
2016-07-21 17:57:59 820
原创 快速编写“专家级”makefile(1.从最简单的Makefile中了解规则)
三个概念: 目标(target):指要干什么依赖关系(dependency):指目标所依赖的其他目标命令(command):指告诉 make 如何生成目标 规则的语法: targets:prerequisite command .... 第一个
2016-07-21 17:56:15 713
原创 C/C++面试题:static(静态)变量的作用
C /: static 的作用: (1)在函数体内,静态变量具有“记忆”功能,即一个被声明为静态的变量在这一函数被调用的过程中其值维持不变 (2)在函数体外(但在模块内),它的作用域范围有限制,即如果一个变量被声明为静态的,那么该变量可以被模块内的所有函数访问,但不能被模块外其他函数访问。如果一个函数被声明为静态的,那么该函数与普通函数作用域
2016-07-21 17:54:02 3388
原创 深入理解程序的结构
程序是被分成段加以管理的,在程序被加载到内存中运行之前,各段是放在程序文件中的。 当程序文件中所需的段被加载到内存中后,将通过运行指令来处理相应的数据。有些数据来源于程序文件中的段,有些是自动生成的。1、段 1.1、指令段 .text 段: 由于处理器只能识别数据和指令。所以不论采用什么高级语言编写
2016-07-17 18:47:52 353
原创 快速理解 .bss、.data和.rodata
全局变量是放在全局内存中的,用static修饰的局部变量也是会放在放全局内存的,它的作用域是局部的,但生命期是全局的。全局强调的是它的生命期,而不是它的作用域,所以有时可能把两者的概念互换。一般来说,在一起定义的两个全局变量,在内存的中位置是相邻的。这是一个简单的常识,但有时挺有用,如果一个全局变量被破坏了,不防先查查其前后相关变量的访问代码,看看是否存在越界访问的可能。在ELF格式的可执
2016-07-12 13:53:35 16715
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人