精华内容
下载资源
问答
  • 我们所写源文件变成可执行程序是需要经过一系列的过程的,也就是我们所说的编译链接,下面简单介绍编译链接原理 编译链接的几个步骤如下图所示: 1.预编译阶段主要工作为: (1)#include 递归展开头文件 (2...

    我们所写源文件变成可执行程序是需要经过一系列的过程的,也就是我们所说的编译链接,下面简单介绍编译链接原理

    编译链接的几个步骤如下图所示:


    1.预编译阶段主要工作为:

    (1)#include  递归展开头文件

    (2)#define  宏定义替换

    (3)删除注释

    (4)添加行符号文件标识

    (5)保留#pragma(交给编译器处理)

    .c/.cpp文件经过预编译处理生成.i文件

    2.编译

    基本可以分为以下几步:

    (1)词法分析

    (2)语法分析

    (3)语义分析

    (4)代码优化

    在检查无误

    编译主要将代码转成汇编代码,并且在这个步骤做了两件很重要的工作,<1>编译器在每个文件中保存一个函数地址符表,该表中存储着当前文件内包含的各个函数地址。<2>因为这一步要生成汇编代码,即一条一条的指令,而调用函数的代码会被编译成call指令,call指令后面跟的时jmp指令的汇编代码地址,而jmp指令后面跟着的才是“被调用的函数编译成汇编代码的第一条指令”的地址,但是call指令后面补充地址的工作是在链接时做的事情。

     

     

     

     

     

     

     

    .i文件经过编译生成.s文件

    3.汇编

    在汇编阶段主要是将指令代码翻译汇编成二进制文件(.o文件)。

    汇编后的.o文件时可重定位的二进制文件

    4.链接

    编译器将生成的多个.o文件来链接到一起生成一个可执行的.exe文件

    链接的时机

     (1)编译时,就是源代码被编译成机器代码时(静态链接器负责);

     (2)加载时,也就是程序被加载到内存时(加载器负责);

    (3)运行时,有应用程序来实施(动态链接器负责);

    链接部分所要做的工作大致可以分为以下几点:

    <1>合并段和符号表

    <2>符号的解析

    <3>分配地址和空间

    <4>符号重定位

    也可以从静态链接与动态链接两部分了解链接:

    (1)静态链接:

    链接器将函数的代码从其所在地(目标文件或静态链接库中)拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。

    为创建可执行的.exe文件,链接器必须要完成的主要任务:

    <1>符号解析:把目标文件中符号的定义和引用联系起来;

    <2>重定位:把符号定义和内存地址对应起来,然后修改所有对符号的引用。

    (2)动态链接

      在此种方式下,函数的定义在动态链接库或共享对象的目标文件中。在编译的链接阶段,动态链接库只提供符号表和其他少量信息用于保证所有符号引用都有定义,保证编译顺利通过。动态链接器(ld-linux.so)链接程序在运行过程中根据记录的共享对象的符号定义来动态加载共享库,然后完成重定位。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码  。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 预编译头文件  在编写程序的时候,有一些头文件被许多文件用到。例如:windows.h这样的系统头文件。如果不采用预编译头文件,那么每个包含windows.h的文件都需要编译这个文件。这将会增加编译时间。正是为了解决...

    预编译头文件

     在编写程序的时候,有一些头文件被许多文件用到。例如:windows.h这样的系统头文件。如果不采用预编译头文件,那么每个包含windows.h的文件都需要编译这个文件。这将会增加编译时间。正是为了解决这个问题,Microsoft Visual C++提出了预编译头文件的解决方法。

      所谓预编译头文件,即将一些指定的头文件预先编译成二进制文件,为了与其他二进制文件区别开来。预编译的头文件生成的二进制文件以.PCH结尾。在Visual C++中默认使用预编译头文件,预编译头文件默认为stdafx.cpp,将那些常用的头文件都放进stdafx.h中去即可。而stdafx.cpp则只包含stdafx.h一个文件。其他所有文件都默认为调用预编译头文件,也即每个.cpp文件都需要在第一行包括#include "stdafx.h"这样的文件。
         当然我们也可以自己定义预编译头文件。例如创建这样两个文件:MyStdafx.h,MyStdafx.cpp。然后将需要提前编译的头文件包含在MyStdafx.h中去,并将MyStdafx.h包含到MyStdafx.cpp中去。将通过Properties\C/C++\Precompiled Header中选择Create Precomliled Header即可。

      Visual C++的其他文件都是默认使用预编译头文件的,并且默认指定了使用的预编译头文件stdafx.h,所以我们在使用了预编译头文件的.cpp文件中必须首行包含stdafx.h。当然我们如果不想使用stdafx.h的话,可以通过Properties\C/C++\Precompiled Header中设置Not Using Precompiled Headers。如此设置,即可以不包含stdafx.h文件了。

      当设定好了预编译头文件时,我们来看一下它是如何工作的。编译都是以.cpp文件为单位开始的,当编译器发现有包括预编译头文件stdafx.h时,并不是将这个文件通过预编译包含进来,而是代替以相就的.pch文件。这样将大大节约编译时间。

     编译链接过程

    当一段代码写好之后进行Build时,主要完成以下三个步骤。
    1.  预处理阶段:即由预处理器对预处理指令(#include、#define和#if)进行处理,在内存中输出翻译单元(一种临时文件)。还有预编译头文件并生成pch文件。
    2.  编译阶段:编译器将内存中的预处理单元,及.pch文件,并编译.cpp文件成生对应的二进制.obj文件(里面包含的是程序的相对地址)。
    3.  链接阶段:链接器将所有obj文件以及所用到的标准库链接成可执行文件.exe。



    转自:http://feihe027.blog.163.com/blog/static/5932583320130256177961/

    展开全文
  • 编译链接过程

    千次阅读 2018-08-24 23:17:54
    编译链接过程 C/C++程序从文本到可执行文件之间是一个复杂的过程. 对于源代码(.c/.cpp)文件我们是不能直接运行的, 必须经过一系列的处理才能转化为机器语言, 再通过链接相应的文件转化为可执行程序. 这个过程称为...

    编译链接过程

    C/C++程序从文本到可执行文件之间是一个复杂的过程. 对于源代码(.c/.cpp)文件我们是不能直接运行的, 必须经过一系列的处理才能转化为机器语言, 再通过链接相应的文件转化为可执行程序. 这个过程称为编译链接过程. 本文篇幅较长, 想直接看分析过程点击这里
    下面是从源代码到可执行文件的整个编译链接的过程:

    整个编译链接过程无非就分为 编译过程链接过程


    <img src='/assert/compiler-linker/1.png'>

    1. 编译过程

    C文件编译过程又可分为: 编译汇编

    1.1 编译

    编译是指编译器读取源程序(字符流), 对之进行词法和语法的分析, 将高级语言指令转换为功能等效的汇编代码.

    简而言之就是将 高级语言(我们这里指C源文件) 代码 转化为 汇编代码

    高级语言指令转化为汇编代码有需要两个过程:

    1.1.1 预处理

    预处理过程通过预处理器来完成, 预处理器是程序中处理输入数据,产生能用来输入到其他程序的数据的程序。输出被称为输入数据预处理过的形式,常用在之后的程序比如编译器中.

    本文只讨论C预处理器, C预处理器是C语言、C++语言的预处理器。用于在编译器处理程序之前预扫描源代码,完成 头文件的包含, 宏扩展, 条件编译, 行控制(line control) 等操作。

    对于C/C++语言预处理一般分为以下几个过程:

    1.1.1.1 包含文件

    所谓包含文件即为头文件 #include 到的文件, 在预处理的过程中会将其加入到预处理器的输出文件中, 以供编译程序处理.

    #include <stdio.h>
    
    int main(void)
    {
        printf("Hello, world!\n");
        return 0;
    }
    1.1.1.2 条件编译
    if-else指令包括#if, #ifdef, #ifndef, #else, #elif and #endif .

    这些指令可以指定不同的宏来决定那些代码执行, 那些不执行. 在预处理的过程中就会将那些不执行的程序进行过滤, 预处理器只输出执行的代码到编译程序中.

    #if VERBOSE >= 2
      print("trace message");
    #endif
    
    #ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix systems */
    # include <unistd.h>
    #elif defined _WIN32 /* _WIN32 is usually defined by compilers targeting 32 or 64 bit Windows systems */
    # include <windows.h>
    #endif
    1.1.1.3 宏定义与扩展

    对于已经定义的宏在进行预处理的过程中直接用已经定义好的宏进行替换, 若定义了 #undef 以后出现的这种宏都不会替换.

    #define <identifier> <replacement token list>                    // object-like macro
    #define <identifier>(<parameter list>) <replacement token list>  // function-like macro, note parameters
    #undef <identifier>                                              // delete the macro
    1.1.1.4 特殊的宏与指令

    对于某些特殊的宏在进行预处理的时候直接进行替换, 比如 C/C++语言定义了标准宏 ____LINE, ____FILE 直接替换为当前行号和文件

    #define WHERESTR  "[file %s, line %d]: "
    #define WHEREARG  __FILE__, __LINE__
    #define DEBUGPRINT2(...)       fprintf(stderr, __VA_ARGS__)
    #define DEBUGPRINT(_fmt, ...)  DEBUGPRINT2(WHERESTR _fmt, WHEREARG, __VA_ARGS__)
    1.1.1.5 Token连接

    Token即为符号, 可以理解为变量名
    使用 ## 运算符(Token Pasting Operator) 可以将两个Token连接成一个Token.
    ## 运算符左侧或右侧如果是另一个宏名,这个宏名将不会被宏展开,而是按照字面值被当作一个token。因此,如果需要 ## 运算符左右的宏名做宏展开,需要使用两层宏的嵌套使用,其中外层的宏展开时也一并把##运算符左右的宏名做宏展开。

    #define DECLARE_STRUCT_TYPE(name) typedef struct name##_s name##_t
    
    DECLARE_STRUCT_TYPE(g_object); // Outputs: typedef struct g_object_s g_object_t;
    1.1.1.6 用户定义的编译错误与警告
    #error "error message"
    #warning "warning message"
    1.1.1.7 编译器相关的预处理特性
    #paragm //提供了编译器特定的预处理功能
    
    //openmp
    #pragma omp parallel for


    1.1.2 编译和优化

    这个过程即为通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码.
    这里进行汇编的过程是通过编译器进行执行的, 在编译器(Compiler)的作用下经过预处理器输入的程序就编译成了汇编代码.


    1.2 汇编

    汇编的过程实际上就是将汇编代码翻译成目标机器语言的过程. 生成的目标文件也就是与源程序在逻辑上等效的机器语言代码.
    生成的机器语言代码被称为目标代码, 生成的二进制文件被称为目标文件, 也成为二进制文件.
    典型的生成的目标文件的数据类型为:

    符号起始区块(BSS Block Started by Symbol的缩写)
    正文段(text segment 或译作代码段)//主要存放程序的指令, 可读可执行不可写
    数据段(data segment)//主要存放全局变量和静态数据. 可读可写可执行

    2. 链接过程

    链接过程是由链接器进行操作的. 链接器(英语:Linker),又译为链接器、连结器,是一个程序,将一个或多个由编译器或汇编器生成的目标文件外加库链接为一个可执行文件。
    在编译过程中已经得到了可执行文件, 在这里主要讨论外加库链接. 现在的大多数操作系统都提供静态链接动态链接这两种链接方式

    以下是连接过程:


    <img src='/assert/compiler-linker/300px-Linker.png'>

    2.1 链接

    2.1.1 静态链接(编译时)

    链接器将函数的代码从其所在地(目标文件或静态链接库中)拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。
    优点: 只需保证在开发者的计算机有正确的库文件,在以二进制发布时不需考虑在用户的计算机上库文件是否存在及版本问题.
    缺点: 生成的可执行文件体积较大。当初正是为了避免此问题,才开发了动态库技术。

    2.1.1 动态链接 (加载, 运行时)

    所谓动态链接,就是把一些经常会共用的代码(静态链接的OBJ程序库)制作成DLL档,当可执行文件调用到DLL档内的函数时,操作系统才会把DLL档加载存储器内,DLL档本身的结构就是可执行档,当程序有需求时函数才进行链接。透过动态链接方式,存储器浪费的情形将可大幅降低。静态链接库则是直接链接到可执行文件。
    DLL档本身也是可执行文件, 在程序执行的时候直接进行动态调用即可.

    2.1.3 静态链接和动态链接的比较

    静态链接动态链接
    编译时加载, 运行时
    lib在编译时就组装进exe文件程序运行时exe文件可以动态的加载dll
    不用考虑计算机库文件版本节省内存, 维护性高
    整个软件包只有exe文件软件包中有exe和dll
    lib文件是外部函数和变量, 在编译时复制进目标程序, 后缀为.adll文件本身是可执行的, 在运行时动态链接, 可以包含源码, 数据, 资源的多种组合, 后缀为.so

    经过链接器的作用形成可执行文件, 最后还要进行一步操作, 进行打包. 即将生成的可执行文件(.exe, .dll, .lib)文件进行打包. 交付给计算机即可运行.


    3. 编译链接过程分析

    我们创建三个文件分别为test.h, test.cmain.c

    //test.c文件
    #include <stdio.h>
    #define __PI__ 3.141592654
    void print_hello(){
        printf("hello world!\n");
    }
    void print_string(char *s){
        printf("%s\n", s);
    }
    double getArea(int r){
        return r*r*__PI__;
    }
    //-------------------------------------------------
    //test.h文件
    //test.h
    void print_hello();
    void print_string(char *s);
    double getArea(int r);
    
    //-------------------------------------------------
    //main.c文件
    #include "test.h"
    #define __HELLO__ print_hello();
    #define __TEMP__ print_string("hello c!");
    
    int main(){
        //test.h --> hello
        print_hello();
        //__HELLO__
        __HELLO__
        //__TEMP__
        __TEMP__
    }
    

    3.1 预处理操作

    gcc -E main.c | tee main.i

    预处理代码 main.i

    # 1 "main.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "main.c"
    # 1 "test.h" 1
    
    void print_hello();
    void print_string(char *s);
    double getArea(int r);
    # 2 "main.c" 2
    
    
    
    int main(){
    
        print_hello();
    
        print_hello();
    
        print_string("hello c!");
    }

    可以发现, 预处理操作将定义的宏全部展开, 包含头文件, 去掉注释等 具体的预处理操作详见1.1.1

    3.2 编译

    gcc -S main.c

    编译生成后缀为.s的汇编代码, 拿出main函数来分析以下

    _main:
    LFB13:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        andl    $-16, %esp
        subl    $16, %esp
        call    ___main
        call    _print_hello      //调用_print_hello函数
        call    _print_hello      //调用_print_hello函数
        movl    $LC3, (%esp)
        call    _print_string     //调用_print_string函数
        movl    $0, %eax
        leave
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc

    3.2 汇编

    汇编生成机器码.o文件, 我们是看不懂的.
    main.otest.o

    //对于.c文件
    gcc -c main.c
    gcc -c test.c

    3.2 链接

    对于得到的上一步汇编得到的.o文件我们进行链接.

    gcc -o main main.o

    这里发现报错了.

    main.o:main.c:(.text+0xf): undefined reference to `print_hello'
    main.o:main.c:(.text+0x14): undefined reference to `print_hello'
    main.o:main.c:(.text+0x20): undefined reference to `print_string

    是因为test.o文件没有打包成我们需要的lib格式文件, 即.a后缀的文件. 进行打包. 打包后的test.a

    ar -rc test.a test.o

    再次链接

    gcc -o main main.o ./test.a

    链接成功, 执行main.exe

    hello world!
    hello world!
    hello c!

    代码在我的个人博客里, 请访问YancyKahn
    以上就是整个编译链接的过程了, 喜欢的话点个赞.


    参考文献

    [1.] http://blog.51cto.com/7905648/1297255
    [2.] http://www.ruanyifeng.com/blog/2014/11/compiler.html
    [3.] https://blog.csdn.net/shenjianxz/article/details/52130111
    [4.] https://zh.wikipedia.org/wiki/C预处理器
    [5.] https://zh.wikipedia.org/wiki/%E7%9B%AE%E6%A0%87%E4%BB%A3%E7%A0%81
    [6.] https://zh.wikipedia.org/wiki/%E9%93%BE%E6%8E%A5%E5%99%A8
    [7.] https://blog.csdn.net/shaderdx/article/details/49929147

    展开全文
  • 平时我们所说的编译主要包括预编译、编译、汇编与链接,这四部分分别都干什么工作,主要职能有哪些,我们一步步探讨总结。 Windows中以2:2划分内核、用户空间,Linux中以1:3划分内核、用户空间。 2、预编译:i 1....

    1、前言

    我们编写的程序代码是怎样运行起来的?到底运行的是什么内容?平时我们所说的编译主要包括预编译、编译、汇编与链接,这四部分分别都干什么工作,主要职能有哪些。
    在这里插入图片描述
    讲述编译之前,我们先要了解程序内存。一个由c/c++编译的程序占用的内存,大致分为以下几个部分:
    1、栈区(stack): 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
    2、堆区(heap): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
    3、全局区(静态区)(static)
    4、文字常量区:常量字符串就是放在这里的。 程序结束后由系统释放
    5、程序代码区:存放函数体的二进制代码。
    在这里插入图片描述
    Windows中以2:2划分内核、用户空间,Linux中以1:3划分内核、用户空间。

    2、代码如何生成

    围绕着内存,编译过程大概如下:
    在这里插入图片描述

    3、预编译:i

    1.#define 宏文本替换
    2.#include 递归展开头文件
    3.#if #endif #elif 删除预编译指令
    4.删除注释
    5.添加行号和文本标识
    6.保留 #pragma 编译器处理

    4、编译:s

    【编译阶段以一个.cpp或者.c文件为单元编译】
    1.词法分析
    2.语法分析
    3.语义分析
    4.代码优化 生成汇编代码

    [inter x86]  //汇编代码
    int a = 10;
    mov dword ptr[a],0Ah //ptr[a] 对a地址解引用后得到a的内存 //0Ah 是10
    

    5、 汇编: o

    可重定位(重入)的二进制文件
    Linux中ELF文件,bss段:段以符号起始,节省空间
    bss段少了一个数据,和虚拟地址空间上的段不同意义。 (bss段中少的数据,位于COM块中)
    强弱符号:强符号是已初始化的全局变量,弱符号是未初始化的全局变量【C++中无强弱符号之分】

    强弱符号规则:
    1.两强:重定义错误 //数据段不可以出现重名
    2.一强一弱:选强符号作为所有地址
    3.两弱:选字节数大的 <编译器处理>
    在汇编完成前,不清楚是否存在强符号无法判断时,则将变量放入COM块中。

    6、 链接

    生成.exe文件 也是ELF文件,有头和.data、.text段等
    //UND 未定义区 //找不到
    1.段合并:相同段合并<一个段映射一个页面>
    合并符号表:同名查找,未找到则用本身查找的弱符号,找到则删除弱符号改用强符号
    2.符号解析(处理UND):未找到对应的符号进行报错 合并UND
    3.分配地址和空间
    4.符号的重定位 //test段 <虚假地址改真实,纠正虚假偏移>
    链接代码:[ld -e main -o run main.o sum.o]

    7、例子

    【Linux】中关于预编译、编译、汇编、链接的代码
    1.[预编译] gcc -E Aff.c -o main.i
    [ls] Aff.c main.i
    2.[编译]gcc -S main.i -o main.s
    [ls]Aff.c mian.i main.s
    3.[汇编]gcc -C mian.s -o main.o
    [ls]Aff.c mian.i main.s main.o a.out
    4.[链接]/a.out //此时是.exe文件(可执行文件)

    加入我们

    在这里插入图片描述

    展开全文
  • 编译与预编译 头文件与源文件 编译与链接 编译 1、编译就是把文本形式源代码(.c/.cpp)翻译为机器语言形式的目标文件(.obj)的过程。 2、 编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译...
  • 预编译的文件扩展名是ii  ...预编译过程主要处理源代码文件当中的以#开头的预编译指令,比如#include就是把头文件插入到这个位置 #define就是把所有的宏定义展开,还有就是删除所有的注释 编译
  • 预编译 编译 汇编 链接 文件 fun.h、fun.cpp、test.cpp fun.i、test.i fun.s、test.s fun.o、test.o projectname.exe 详解: 1.预编译预编译过程主要做4件事: ①...
  • 预编译过程:预编译过程主要处理那些源代码文件中的以”#”开始的预编译指令。比如:”#include”,”#define”等,主要处理规则如下: (1)将所有的”#define”删除,并且展开所有的宏定义。 (2)处理所有条件...
  • 预编译的文件扩展名是ii gcc -E hello.c -o hello.i 预编译过程主要处理源代码文件当中的以#开头的预编译指令,比如#include就是把头文件插入到这个位置 #define就是把所有的宏定义展开,还有就是删除所有的注释...
  • GCC 预编译-编译-链接-加载

    千次阅读 2014-07-25 11:42:30
    广义的代码编译过程,实际上应该细分为:预处理,编译,汇编,链接。 预处理过程,负责头文件展开,宏替换,条件编译的选择,删除注释等工作。gcc –E表示进行预处理。 编译过程,负载将预处理生成的文件,...
  • C 处理器在程序执行之前检查程序(故称为处理器),根据程序中的处理器指令,处理器把符号缩写替换成其表示的内容。处理器可以包含程序所需要的其他文件,可以选择让编译器查看那些代码。处理器并不知道...
  • 编译链接的基本步骤

    2016-07-21 00:26:25
    因为现在的开发环境都是集成开发环境,所以我们很少需要关注一段代码在计算机中编译链接的过程。但是事实上,通常一段代码需要四个步骤才能完成从编译到链接的过程,分别是预处理,编译,汇编和链接。  编译链接...
  • 编译链接的全过程

    千次阅读 2016-10-01 11:24:46
    我们知道一个.c, .cpp文件到可执行文件经历了4个阶段:预编译,编译,汇编,链接;下面就介绍一下各个过程的完成的工作预编译 1:将所有的#define删除,并展开所有的宏定义; 2:处理所有的预编译指令,例如:#if,#...
  • 【C++】预编译、编译、汇编、链接

    万次阅读 多人点赞 2018-11-15 01:02:20
    符号的重定位 //test段 链接代码:[ld -e main -o run main.o sum.o] 【Linux】中关于预编译、编译、汇编、链接的代码 1.[预编译] gcc -E Aff.c -o main.i [ls] Aff.c main.i 2.[编译]gcc -S main.i -o ...
  • 编译链接的过程做了什么

    千次阅读 2019-03-13 23:36:09
    预编译,编译,汇编,链接预编译阶段(预编译之后生成.i文件)主要处理那些源代码文件中以“#”开始的预编译指令,例如#include,#define等。主要规则如下: 1,删除所有的#define,展开所有的宏定义; 2,...
  • 编译链接原理

    千次阅读 2018-07-04 21:31:03
    在这里将简单介绍下程序的编译链接原理。 在ANSI C的任何一种实现中,存在两种环境翻译环境和执行环境。翻译环境主要将源代码转化为可执行的机器指令。执行环境用于实际执行代码。在翻译环境中,主要进行编译和...
  • android ART编译预优化

    千次阅读 2017-03-14 10:17:22
    编译预优化 DEX文件编译比较花费时间。这在OTA或者工厂首次烧入程序后非常明显。 可以在BoardConfig.mk文件中使能编译预优化,在编译时将会为APK/jar做Dex优化(dex2oat): WITH_DEXPREOPT := true 如果完全的编译...
  • 预编译与编译

    2020-09-16 23:52:32
    预编译阶段:主要是编译器执行代码文本处理工作,并不会进行语法检查 主要执行三大类预编译命令 宏定义:代码文本替换功能,将使用了宏的地方采取宏定义方式直接展开 条件编译:代码文本剪切功能,根据设定的条件...
  • 项目属性–预编译头–不使用预编译
  • vs2013的项目换了一个文件夹编译,出现error LNK2011: 未链接预编译对象;映像可能不能运行
  • 编译链接的过程

    千次阅读 2019-03-30 22:01:57
    文章目录预编译编译汇编链接地址与空间的分配重定位 预编译 预编译:(处理所有预编译的指令如 #inclue #if #endif #define #ifdef 等) (1)宏替换 (2)头文件的引入 (3)注释的替换(用空格替换) (4)添加...
  • 四:预编译、编译、汇编、链接 //详情参考《程序员的自我修养》1-6章 精简版: //在原文基础上做补充和修改 参考原文:https://blog.csdn.net/weixin_40740059/article/details/84075653 如图:c程序的4G虚拟...
  • c++ 预编译

    千次阅读 2017-03-27 16:57:27
    预编译是c++编译的最初部分,它的工作是在编译之前对程序内容进行最有的取舍处理,使得一些语句参加编译,而另一些语句不参加编译。常用的预编译指令是: 1、包含指令:#include 2、条件指令:#if、#elif、#else、#...
  • gcc中预编译、编译、汇编、链接   一、预编译 操作步骤:gcc -E test.c -o test.i 作用:处理关于 “#” 的指令 (1)删除#define,展开所有宏定义。例#define portnumber 3333 (2)处理条件预编译 #if, #ifdef, #...
  • 编译链接过程 【1】预处理 源代码被预编译为一个 .i文件 在Linux下,对于一个已经编写好的main.c源程序,代码 gcc -E mainn.c -o main.i 完成对程序的预处理。 或者:cpp main.c &gt; main.i 预处理主要...
  • 深入程序编译链接和装载过程

    千次阅读 多人点赞 2018-12-06 12:56:02
    预编译 编译 汇编 链接 深入编译链接和运行 CPU、内存 与 I/O 32位4GLinux虚拟地址空间布局 指令和数据 分析二进制可重定位目标文件main.o 的组成 强符号与弱符号 符号表 链接过程分析 可执行文件分析 ...
  • C语言的编译链接过程详解

    千次阅读 2018-08-04 11:43:31
    我们将对C语言的这种处理过程称为编译链接编译就是把文本形式源代码翻译为机器语言形式的目标文件过程。 链接是把目标文件、操作系统的启动代码和用到的库文件进行组织最终形成可执行代码的过程。编译链接...
  • c语言中编译链接的整个过程

    千次阅读 2016-10-19 13:33:34
    C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的...
  • 第一个阶段是预编译阶段,在正式的编译阶段之前进行。预处编译段将根据已放置在文件中的预处理指令来修改源文件的内容。如#include指令就是一个预处理指令,它把头文件的内容添加到.cpp文件中。宏替换也是在预编译...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 120,492
精华内容 48,196
关键字:

编译链接预编译