精华内容
下载资源
问答
  • 64位 gcc 编译32位程序

    2021-01-07 19:39:19
    gcc 编译32位程序只需要加参数 -m32即可,如 gcc -m32 hello.c 笔者的系统为: root@book-virtual-machine:~# cat /proc/version Linux version 4.13.0-41-generic (buildd@lgw01-amd64-028) (gcc version 5.4.0 ...
  • windows下使用 armgcc编译器编译stm32f103vet6+freeRTOS源码,内附带源码,编译命令。
  • gcc编译文件

    2017-10-31 10:08:04
    gcc编译文件gcc编译文件gcc编译文件gcc编译文件gcc编译文件
  • GCC编译命令 Gcc命令行详解 Gcc命令行详解 Gcc命令行详解
  • gcc编译生成可执行文件的过程中发生了什么

    千次阅读 多人点赞 2019-04-15 11:46:05
    一直好奇程序的编译过程到底做了哪些工作,后来学会在Ubuntu上使用gcc编译程序,知道了生成可执行文件需要分为预编译、编译、汇编和链接4个步骤,逐渐了解了其中的细节,但是过一段时间之后总是记不太清楚了,所以...

    前言

    一直好奇程序的编译过程到底做了哪些工作,后来学会在Ubuntu上使用gcc编译程序,知道了生成可执行文件需要分为预编译、编译、汇编和链接4个步骤,逐渐了解了其中的细节,但是过一段时间之后总是记不太清楚了,所以总结一下增强记忆,同时方便日后查找使用。

    编译方式

    一步到位

    使用gcc命令可以一步将main.c源文件编译生成最终的可执行文件main_direct

    gcc main.c –o main_direct
    

    分步执行

    gcc的编译流程通常认为包含以下四个步骤,实际上就是将上面的命令分成4步执行,这也是gcc命令实际的操作流程,生成的可执行文件main与上面单条命令生成的可执行文件main_direct是一模一样的

    • 预处理,生成预编译文件(.i文件):gcc –E main.c –o main.i
    • 编译,生成汇编代码(.s文件):gcc –S main.i –o main.s
    • 汇编,生成目标文件(.o文件):gcc –c main.s –o main.o
    • 链接,生成可执行文件(executable文件):gcc main.o –o main

    编译流程

    这里的编译是指将源文件(.c)生成可执行文件(executable)的这个完整的过程,而不是上面提到的四个步骤中的第二步,为了弄清楚编译过程究竟都做了哪些工作,接下来我们可以分步骤来看一下gcc编译.c文件的过程,了解了每一步的内容,也就明白了整个编译流程,先给出源文件 mian.c 的源代码。

    #include <stdio.h>
    #define A 100
    
    // calc sum
    int sum(int a, int b)
    {
        return a + b;
    }
    
    int main()
    {
        int b = 1;
        int c = sum(A, b);
        printf("sum = %d\n", c);
    
        return 0;
    }
    

    预处理

    预处理又叫预编译,是完整编译过程的第一个阶段,在正式的编译阶段之前进行。预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容,对于C语言来说预处理的可执行程序叫做 cpp,全称为C Pre-Processor(C预处理器),是一个与 C 编译器独立的小程序,预编译器并不理解 C 语言语法,它仅是在程序源文件被编译之前,实现文本替换的功能。简单来说,预处理就是将源代码中的预处理指令根据语义预先处理,并且进行一下清理、标记工作,然后将这些代码输出到一个 .i 文件中等待进一步操作。

    一般地,C/C++ 程序的源代码中包含以 # 开头的各种编译指令,被称为预处理指令,其不属于 C/C++ 语言的语法,但在一定意义上可以说预处理扩展了 C/C++。根据ANSI C 定义,预处理指令主要包括:文件包含、宏定义、条件编译和特殊控制等4大类。

    预处理阶段主要做以下几个方面的工作:

    1. 文件包含:#includeC 程序设计中最常用的预处理指令,格式有尖括号 #include <xxx.h> 和双引号 #include "xxx.h" 之分,分别表示从系统目录下查找和优先在当前目录查找,例如常用的 #include <stdio.h> 指令,就表示使用 stdio.h 文件中的全部内容,替换该行指令。

    2. 添加行号和文件名标识: 比如在文件main.i中就有类似 # 2 "main.c" 2 的内容,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。

    3. 宏定义展开及处理: 预处理阶段会将使用 #define A 100 定义的常量符号进行等价替换,文中所有的宏定义符号A都会被替换成100,还会将一些内置的宏展开,比如用于显示文件全路径的__FILE__,另外还可以使用 #undef 删除已经存在的宏,比如 #undef A 就是删除之前定义的宏符号A

    4. 条件编译处理:#ifdef#ifndef#else#elif#endif等,这些条件编译指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理,将那些不必要的代码过滤掉,防止文件重复包含等。

    5. 清理注释内容: // xxx/*xxx*/ 所产生的的注释内容在预处理阶段都会被删除,因为这些注释对于编写程序的人来说是用来记录和梳理逻辑代码的,但是对编译程序来说几乎没有任何用处,所以会被删除,观察 main.i 文件也会发现之前的注释都被删掉了。

    6. 特殊控制处理: 保留编译器需要使用 #pragma 编译器指令,另外还有用于输出指定的错误信息,通常来调试程序的 #error 指令。

    查看main.i文件

    编译

    编译过程是整个程序构建的核心部分,也是最复杂的部分之一,其工作就是把预处理完生成的 .i 文件进行一系列的词法分析、语法分析、语义分析以及优化后产生相应的汇编代码文件,也就是 .s 文件,这个过程调用的处理程序一般是 cc 或者 ccl。汇编语言是非常有用的,因为它给不同高级语言的不同编译器提供了可选择的通用的输出语言,比如 CFortran 编译产生的输出文件都是汇编语言。

    1. 词法分析: 主要是使用基于有线状态机的Scanner分析出token,可以通过一个叫做 lex 的可执行程序来完成词法扫描,按照描述好的词法规则将预处理后的源代码分割成一个个记号,同时完成将标识符存放到符号表中,将数字、字符串常量存放到文字表等工作,以备后面的步骤使用。

    2. 语法分析: 对有词法分析产生的token采用上下文无关文法进行分析,从而产生语法树,此过程可以通过一个叫做 yacc 的可执行程序完成,它可以根据用户给定的语法规则对输入的记号序列进行解析,从而构建一棵语法树,如果在解析过程中出现了表达式不合法,比如括号不匹配,表达式中缺少操作符、操作数等情况,编译器就会报出语法分析阶段的错误。

    3. 语义分析: 此过程由语义分析器完成,编译器 cc 所能分析的语义都是静态语义,是指在编译期间可以确定的语义,通常包括声明和类型的匹配,类型的转换等。比如将一个浮点型的表达式赋值给一个整型的表达式时,语义分析程序会发现这个类型不匹配,编译器将会报错。而动态语义一般指在运行期出现的语义相关问题,比如将0作为除数是一个运行期语义错误。语义分析过程会将所有表达式标注类型,对于需要隐式转换的语法添加转换节点,同时对符号表里的符号类型做相应的更新。

    4. 代码优化: 此过程会通过源代码优化器会在源代码级别进行优化,针对于编译期间就可以确定的表达式(例如:100+1)给出确定的值,以达到优化的目的,此外还包括根据机器硬件执行指令的特点对指令进行一些调整使目标代码比较短,执行效率更高等操作。

    查看main.s文件

    汇编

    汇编过程是整个程序构建中的第三步,是将编译产生的汇编代码文件转变成可执行的机器指令。相对来说比较简单,每个汇编语句都有相对应的机器指令,只需根据汇编代码语法和机器指令的对照表翻译过来就可以了,最终生成目标文件,也就是 .o 文件,完成此工作的可执行程序通常是 as。目标文件中所存放的也就是与源程序等效的目标的机器语言代码,通常至少包含代码段和数据段两个段,并且还要包含未解决符号表,导出符号表和地址重定向表等3个表。汇编过程会将extern声明的变量置入未解决符号表,将static声明的全局变量不置入未解决符号表,也不置入导出符号表,无法被其他目标文件使用,然后将普通变量及函数置入导出符号表,供其他目标文件使用。

    1. 代码段: 包含主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。

    2. 数据段: 主要存放程序中要用到的各种全局变量或静态的数据,一般数据段都是可读,可写,可执行的。

    3. 未解决符号表: 列出了在本目标文件里有引用但不存在定义的符号及其出现的地址。

    4. 导出符号表: 列出了本目标文件里具有定义,并且可以提供给其他目标文件使用的符号及其在出现的地址。

    5. 地址重定向表: 列出了本目标文件里所有对自身地址的引用记录。

    查看main.o文件

    链接

    链接过程是程序构建过程的最后一步,通常调用可执行程序 ld 来完成,可以简单的理解为将目标文件和库文件打包组装成可执行文件的过程,其主要内容就是把各个模块之间相互引用的部分都处理好,将一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得各个模块之间能够正确的衔接,成为一个能够被操作系统装入执行的统一整体。

    虽然汇编之后得到的文件已经是机器指令文件,但是依然无法立即执行,其中可能还有尚未解决的问题,比如源代码 main.c 中的 printf 这个函数名就无法解析,需要链接过程与对应的库文件对接,完成的重定位,将函数符号对应的地址替换成正确的地址。前面提到的库文件其实就是一组目标文件的包,它们是一些最常用的代码编译成目标文件后打成的包。比如 printf的头文件是 stdio.h,而它的实现代码是放在动态库 libc.so.6 中的,链接的时候就要引用到这个库文件。

    从原理上讲,连接的的工作就是把一些指令对其他符号地址的引用加以修正,主要包括了地址和空间分配、符号决议和重定位等步骤,根据开发人员指定的链接库函数的方式不同,链接过程可分为静态链接和动态链接两种,链接静态的库,需要拷贝到一起,链接动态的库需要登记一下库的信息。

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

    2. 动态链接: 函数的代码被放到动态链接库或共享对象的某个目标文件中。链接处理时只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在这样该程序在被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间,根据可执行程序中记录的信息找到相应的函数代码。这种连接方法能节约一定的内存,也可以减小生成的可执行文件体积。

    查看main可执行文件

    总结

    • gcc编译器的工作过程:源文件 --> 预处理 --> 编译 --> 汇编 --> 链接 --> 可执行文件
    • gcc编译过程文件变化:main.c --> main.i --> mian.s --> main.o --> main
    • 通过上面分阶段的解释编译过程,我们也明白了gcc其实只是一个后台程序的包装,它会根据阶段要求来调用 cppccasld 等命令

    源代码

    整个编译过程产生的中间文件及最终结果可以通过传送门—— gcc编译项目 来获得,其中还有gccg++分别调用的对比,查看生成的文件可以发现,同样的源代码使用gccg++生成的文件是不一样的,总的来说使用g++编译生成的可执行文件要大一些。
    gcc_compile

    展开全文
  • GCC编译选项详解

    千次阅读 2019-08-30 15:18:35
    1、gcc包含的c/c++编译器gcc,cc,...一般c程序就用gcc编译,c++程序就用g++编译  2、gcc的基本用法 gcc test.c这样将编译出一个名为a.out的程序gcc test.c -o test这样将编译出一个名为test的程序,-o参数用来指...

         

          1、gcc包含的c/c++编译器gcc,cc,c++,g++

            gcc和cc是一样的,c++和g++是一样的。一般c程序就用gcc编译,c++程序就用g++编译 

      2、gcc的基本用法

            gcc test.c这样将编译出一个名为a.out的程序gcc test.c -o test这样将编译出一个名为test的程序,-o参数用来指定生成程序的名字 

      3、为什么会出现undefined reference to ‘xxxxx’错误

           首先这是链接错误,不是编译错误,也就是说如果只有这个错误,说明你的程序源码本身没有问题,是你用编译器编译时参数用得不对,你没有指定链接程序要用到得库,比如你的程序里用到了一些数学函数,那么你就要在编译参数里指定程序要链接数学库,方法是在编译命令行里加入-lm。 
      4、-l参数和-L参数

             -l参数就是用来指定程序要链接的库(库文件在/lib、/usr/lib和/usr/local/lib下),-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。好了现在我们知道怎么得到库名了,比如我们自已要用到一个第三方提供的库名字叫libtest.so,那么我们只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里的函数,我们还需要与libtest.so配套的头文件)。

          放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了,但如果库文件没放在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:“/usr/bin/ld: cannot find -lxxx”,也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了(-L指定路径,-l指定具体库,配合使用),比如常用的X11的库,它放在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest。

         另外,大部分libxxxx.so只是一个链接,以RH9为例,比如libm.so它链接到/lib/libm.so.x,/lib/libm.so.6又链接到/lib/libm-2.3.2.so,如果没有这样的链接,还是会出错,因为ld只会找libxxxx.so,所以如果你要用到xxxx库,而只有libxxxx.so.x或者libxxxx-x.x.x.so,做一个链接就可以了ln -s libxxxx-x.x.x.so libxxxx.so手工来写链接参数总是很麻烦的,还好很多库开发包提供了生成链接参数的程序,名字一般叫xxxx-config,一般放在/usr/bin目录下,比如gtk1.2的链接参数生成程序是gtk-config,执行gtk-config –libs就能得到以下输出”-L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm”,这就是编译一个gtk1.2程序所需的gtk链接参数,xxx-config除了–libs参数外还有一个参数是–cflags用来生成头文件包含目录的,也就是-I参数,在下面我们将会讲到。你可以试试执行gtk-config –libs –cflags,看看输出结果。现在的问题就是怎样用这些输出结果了,最笨的方法就是复制粘贴或者照抄,聪明的办法是在编译命令行里加入这个xxxx-config --libs --cflags,比如编译一个gtk程序:gcc gtktest.c gtk-config --libs --cflags这样就差不多了。注意不是单引号,而是1键左边那个键。除了xxx-config以外,现在新的开发包一般都用pkg-config来生成链接参数,使用方法跟xxx-config类似,但xxx-config是针对特定的开发包,但pkg-config包含很多开发包的链接参数的生成,用pkg-config --list-all命令可以列出所支持的所有开发包,pkg-config的用法就是pkg-config pagName --libs --cflags,其中pagName是包名,是pkg-config--list-all里列出名单中的一个,比如gtk1.2的名字就是gtk+,pkg-config gtk+ --libs --cflags的作用跟gtk-config --libs --cflags是一样的。比如:gcc gtktest.cpkg-config gtk+ –libs –cflags`。 

      5、-include和-I参数

             -include用来包含头文件,但一般情况下包含头文件都在源码里用#include xxxxxx实现,-include参数很少用。-I参数是用来指定头文件目录,/usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/include里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude参数了,如果不加你会得到一个”xxxx.h: No such file or directory”的错误。-I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定。上面我们提到的–cflags参数就是用来生成-I参数的。 

      6、-O参数

             这是一个程序优化参数,一般用-O2就是,用来优化程序用的,比如gcc test.c -O2,优化得到的程序比没优化的要小,执行速度可能也有所提高(我没有测试过)。 

      7、-shared参数

           编译动态库时要用到,比如gcc -shared test.c -o libtest.so 

      8、几个相关的环境变量

            PKG_CONFIG_PATH:用来指定pkg-config用到的pc文件的路径,默认是/usr/lib/pkgconfig,pc文件是文本文件,扩展名是.pc,里面定义开发包的安装路径,Libs参数和Cflags参数等等。

           CC:用来指定c编译器。

           CXX:用来指定cxx编译器。

           LIBS:跟上面的–libs作用差不多。

          CFLAGS:跟上面的–cflags作用差不多。

          CC,CXX,LIBS,CFLAGS手动编译时一般用不上,在做configure时有时用到,一般情况下不用管。环境变量设定方法:export ENV_NAME=xxxxxxxxxxxxxxxxx 

           9、关于交叉编译

             交叉编译通俗地讲就是在一种平台上编译出能运行在体系结构不同的另一种平台上,比如在我们地PC平台(X86 CPU)上编译出能运行在sparc CPU平台上的程序,编译得到的程序在X86 CPU平台上是不能运行的,必须放到sparc CPU平台上才能运行。当然两个平台用的都是linux。这种方法在异平台移植和嵌入式开发时用得非常普遍。

            相对与交叉编译,我们平常做的编译就叫本地编译,也就是在当前平台编译,编译得到的程序也是在本地执行。用来编译这种程序的编译器就叫交叉编译器,相对来说,用来做本地编译的就叫本地编译器,一般用的都是gcc,但这种gcc跟本地的gcc编译器是不一样的,需要在编译gcc时用特定的configure参数才能得到支持交叉编译的gcc。

            为了不跟本地编译器混淆,交叉编译器的名字一般都有前缀,比如sparc-xxxx-linux-gnu-gcc,sparc-xxxx-linux-gnu-g++ 等等10。交叉编译器的使用方法使用方法跟本地的gcc差不多,但有一点特殊的是:必须用-L和-I参数指定编译器用sparc系统的库和头文件,不能用本地(X86)的库(头文件有时可以用本地的)。例子:sparc-xxxx-linux-gnu-gcc test.c -L/path/to/sparcLib -I/path/to/sparcInclude

    展开全文
  • GCC编译过程及基本命令总结

    千次阅读 多人点赞 2018-12-30 16:17:14
    GCC即GNU Compiler Collection,原本只是针对C语言的编译工具,现在已经变成了一个工具集,包含了C、C++、JAVA等语言的集合体。 管理和维护:由GNU项目负责。 二、GCC对C、C++的编译流程 (1) 预处理...

    一、GCC简介

    GCC即GNU Compiler Collection,原本只是针对C语言的编译工具,现在已经变成了一个工具集,包含了C、C++、JAVA等语言的集合体。

    管理和维护:由GNU项目负责。

    二、GCC对C、C++的编译流程

    (1) 预处理(Preprocessing) 

    --宏替换;

    --删除注释;

    --处理预处理指令,如#include,#ifdef,头文件都被展开,拼接所有头文件到一个文件中。

    (2) 编译(Compilation)        

    --词法分析,识别单词,确认词类;比如 int i;知道 int 是一个类型,i是一个关键字以及判断i的名字是否合法

    --语法分析,识别短语和句型的语法属性;

    --语义分析,确认单词、短语和句型的语义特征;

    --代码优化,修辞、文本编辑;

    --代码生成,生成译文(.s文件,统一代码在不同系统中的.s文件不一致)。

    (3)汇编(Assemby)             

    --把汇编语言代码翻译成目标机器指令(生成目标文件,.o文件)。

    编译器把一个cpp编译为目标文件的时候,除了要在目标文件里写入cpp里包含的数据和代码,还要至少提供3个表:未解决符号表,导出符号表和地址重定向表。

    未解决符号表,提供了所有在该编译单元里引用但是定义并不在本编译单元里的符号及其出现的地址。

    导出符号表,提供了本编译单元具有定义,并且愿意提供给其他编译单元使用的符号及其地址。

    地址重定向表,提供了本编译单元所有对自身地址的引用的记录。

    (4) 链接(Linking)                 

    --将所有.o文件及引用到的动态链接库文件中的函数链接到一起,生成可执行文件(.out文件)。

    三、GCC的基本使用(以下选项在g++中同样试用,一般c程序就用gcc编译,c++程序就用g++编译

    基本使用格式 :    $ gcc  [选项]  <文件名>

    (1) -o 设置gcc处理结果的文件名为<文件名>

    如 gcc main.c -o main  ,即为将编译结果的文件名设置为main,如果不使用-o命令,则编译结果是默认的文件名(假如被处理的源文件为source.suffix,若省略了-o选项,则生成的可执行文件默认为a.out,目标文件默认名为source.o,汇编文件默认为source.s)。

    例如对于这个main.c

    -- 执行 gcc main.c (输出默认文件名)

    -- 执行 gcc main.c -o main (指定gcc处理结果的文件名为main)

    (2) -c 只编译,不链接

    执行 gcc -o main.c (结果为.o文件) 

    一般对于包含对个.c文件的大工程,首先把每个.c文件编译成独立的.o文件,然后把所有.o文件进行链接生成可执行文件。 

    (3) -E 预编译 (将所有的头文件和宏都拼接到一个.c文件中)

     执行 gcc -E main.c (可见在main()函数之前,所有的头文件和宏定义都被包含进来(先把头文件copy过来,然后对宏进行替换))

     也就是说对于一个程序,预编译会把所有的头文件和宏定义都拼接到一个文件中,因为其实一个程序就算其包含了很多子文,但是最终都是编译一个文件。

    (4) -S 只编译不汇编

    执行 gcc -S main.c (生成.s文件,同意程序在不同体系下的计算机中生成的汇编文件是不一致的)

    (5) -g 生成调试信息(debug版本)

    执行 gcc -g main.c -o main_d ,生成带调试信息的版本,并令生成的文件名为“main_d”。可见加了-g的版本比普通版本所占空间更大,因为debug版本加入了调试信息,会把代码编进去,后面可以使用GDB工具进行调试跟进


    【多目录编译】

    (6) -I 添加头文件路径(多文件目录下)

    例如有如下目录:

    --person

            --person/person.h

            --person/person.cpp

    --test

             --test/main.cpp

    main.cpp如下

    person.h如下 

    person.cpp如下

     编译过程如下:

    (a). 执行 g++ -c person.cpp ,首先单独编译person.cpp生成目标文件person.o 。

    (b). 执行 g++ main.cpp ../person/person.o -o main -I ../person,编译person.o和main.cpp,-I添加头文件目录。


    【静态编译】

    (7)  -static 静态编译(若指定为静态编译,则会把所有引用到的系统文件都指定成静态库,全部编译到这个可执行文件中)

    使用ldd可以查看程序所引用到的动态库。

    执行 ldd main ,可见一个简单的程序都引用了很多库。

    执行  g++ main.cpp ../person/person.o -o main_static -I ../person -static ,将程序进行静态编译(使用个g++是因为gcc编译c++找不到库文件)。

    然后再使用ldd main_static查看调用的动态库,可以发现它不调用任何动态库。

     而且可执行文件的大小变得非常大。

    注:大部分情况下不建议使用静态方式进行编译,因为其最大的问题就是编译时间太长,稍微大点的项目编译要几分钟,但是它在其他环境下运行比较简单,不需要配置环境依赖。


    【动态编译】

    (8) -fpic -shared  前者指定函数和代码位置不相关,设置之后可以使用-shared将其设置为动态链接库动态链接库在linux中的命名规则为 lib+name+.so,引用的时候只要使用name就行了)。

    执行 gcc person.cpp -fpic -shared -o libperson.so ,将person.cpp编译成动态链接库 libperson.so。

    (9) -L -l(小写的L) 前者指定动态链接库的所在目录,后者指定需要链接的动态链接库(不加lib 和.so)

    执行 g++ main.cpp -o main -I../person -L../person -lperson ,在编译main时使用-I(大写的i)指定头文件目录,使用-L指定董涛链接库目录,使用-lperson指定需要在编译时链接libperson.so这个动态链接库文件。

     注意:执行通过动态链接而编译生成的可执行文件main时,需要指定动态链接库文件libperson.so的路径,否则运行数失败。

    解决方法有两种:

    (a) 将需要链接的动态链接库文件libperson.so拷贝到系统的path路径下。

    (b) 写执行脚本export LD_LIBRARY_PATH=../person,添加临时路径。

     使用ldd命令查看main依赖,可见确实在../person目录下找到的。

     

    展开全文
  • Linux C/C++编程之(八)gcc编译

    千次阅读 2020-06-29 22:22:34
    文章目录一、概述二、gcc编译的四个阶段三、gcc命令四、gcc编译1. gcc -E2. gcc -S: 生成汇编指令3. gcc - c: 生成二进制文件4. gcc -I: (包含头文件)5. gcc -o: 指定输出6. gcc -D xxxx: 编译时传递宏7. gcc -g: ...

    一、概述

    在这里插入图片描述

    二、gcc编译的四个阶段

    在这里插入图片描述

    三、gcc命令

    在这里插入图片描述

    四、gcc编译

    1. gcc -E

    预处理/头文件展开/宏替换
    在这里插入图片描述

    2. gcc -S: 生成汇编指令

    在这里插入图片描述

    3. gcc - c: 生成二进制文件

    在这里插入图片描述

    4. gcc -I: (包含头文件)

    在这里插入图片描述

    5. gcc -o: 指定输出

    在这里插入图片描述

    6. gcc -D xxxx: 编译时传递宏

    -D之前
    在这里插入图片描述
    在这里插入图片描述
    -D之后
    在这里插入图片描述

    7. gcc -g: 用于gdb调试

    在这里插入图片描述

    8. gcc -Wall: 多警告

    在这里插入图片描述

    9. gcc -lstdc++: 指定c++方式编译

    在这里插入图片描述
    g++ 执行 -o 输出
    在这里插入图片描述
    gcc 执行 -o 输出在这里插入图片描述

    展开全文
  • gcc编译c++文件

    万次阅读 2019-02-15 15:47:30
    gcc编译c语言的,默认情况下,如果直接编译c++程序,会报错: [root@server demo2]# ls hello.cpp [root@server demo2]# cat hello.cpp  #include &lt;iostream&gt; using namespace std; int main(){ ...
  • Linux 内核和许多其他自由软件以及开放源码应用程序都是用 C 语言编写并使用 GCC 编译的。
  • gcc 编译 优化 选项

    2010-06-04 23:16:13
    gcc 编译 优化 选项 英文的编译器优化选项
  • GCC 编译命令

    万次阅读 多人点赞 2018-12-25 09:58:00
    GCC 编译器在编译一个C语言程序时需要经过以下 4 步: 将C语言源程序预处理,生成.i文件。 预处理后的.i文件编译成为汇编语言,生成.s文件。 将汇编语言文件经过汇编,生成目标文件.o文件。 将各个模块的.o文件...
  • gcc编译工具常用命令以及汇编语言

    千次阅读 2020-10-15 16:27:04
    文章目录一、Linux GCC常用命令二、GCC编译器背后的故事二、使用步骤1.引入库2.读入数据总结 一、Linux GCC常用命令 1 新建一个文件test,代码如下: #include <stdio.h> int main(void) { printf("Hello ...
  • gcc编译的四个阶段

    千次阅读 2019-09-04 23:05:34
    gcc编译的四个阶段 如下图: 参数意义: -E Preprocess only; do not compile, assemble or link;只预处理,不会编译、汇编、链接 -S Compile only; do not assemble or link;只编译,不会汇编、链接 -c Compile and...
  • gcc 编译C语言最全命令

    千次阅读 2020-03-05 23:25:01
    gcc 编译命令 最简单的编译命令是:gcc main.c 默认生成的可执行文件是 a.out,如果需要指定输出文件,则需要使用如下的命令:gcc main.c – o main 使用-Wall 选项可以输出所有的警告信息: gcc -Wall main.c -o main ...
  • GCC编译常用命令

    万次阅读 多人点赞 2018-05-05 23:45:02
    GCC 编译命令 ----------------加入新公司后,基本上是一键式打包脚本,对于GCC基本上快忘了,重新拾起。GCC命令提供了非常多的命令选项,但并不是所有都要熟悉,初学时掌握几个常用的就可以了,到后面再慢慢学习...
  • GCC编译选项参数介绍

    千次阅读 2018-07-08 17:30:36
    gcc和g++分别是gnu的c和c++编译器,下面是整理的常用编译选项参数:#(1). -x: 设定文件所使用的语言,使文件后缀名无效,如下,执行完后生成test.o gcc -c -x c++ test.jpg #(2). -c: 只编译生成目标文件即*.o,只...
  • gcc编译链接头文件和库文件

    千次阅读 2019-11-24 23:51:31
    GCC与头文件 gcc -参数: -I ( i 的大写) :指定头文件路径(相对...gcc头文件的搜索路径: 头文件 gcc编译时如何去寻找所需要的头文件: 头文件的搜索会从-I指定的目录开始; 然后搜索gcc的环境变量 C_INCLU...
  • gcc编译参数的顺序问题 gcc编译参数的顺序问题 gcc编译参数的顺序问题
  • gcc编译过程,helloworld举例

    千次阅读 2019-04-15 23:28:04
    gcc编译过程,helloworld举例 编译过程图示: 整个过程可分为四个阶段逐步完成:预处理,编译,汇编,链接 一个C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)、和链接(linking)才能变成...
  • gcc编译参数

    千次阅读 2018-10-28 16:42:58
    gcc 编译流程: 预处理-Pre-Processing -E 选项指示编译器仅对输入文件进行预处理。当这个选项被使用时, 预处理器的输出被送到标准输出而不是储存在文件里 gcc -E code.c -o code.i //.i文件 编译-Compiling -S ...
  • windows通过gcc编译c语言

    千次阅读 2019-03-20 21:55:29
    GCC(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器。它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分。GCC原本作为GNU操作系统的官方编译器,现已被大多数类Unix操作系统...
  • 通过.rc资源文件的方式来实现自定义GCC编译出来的可执行程序的.ico图标的简单C++源码。
  • Linux下GCC编译C语言

    万次阅读 多人点赞 2018-06-12 20:49:50
    Linux下GCC编译C语言Linux下GCC编译C语言 1.创建一个.C文件 # vi/vim name.c 2.编译name.c文件,生成可执行文件 # gcc name.c 3.执行文件,在默认情况下产生的可执行程序名为a.out # ./a.out 4.通常可以...
  • GCC编译过程,了解编译原理

    千次阅读 2018-12-09 20:00:16
    1、GCC编译过程分解 以HelloWorld程序为例 2、预编译 规则: 命令:gcc -E XXX.c -o XXX.i   3、编译 词法分析、语法分析、语义分析及优化 ---------------&gt;&gt; 汇编代码文件 命令:...
  • gcc编译GTK+程序

    千次阅读 2019-10-15 10:28:04
    gcc编译 $ gcc Hello.c -o Hello `pkg-config --cflags --libs gtk+-3.0` pkg-config :返回关于已安装库的元数据信息。如果我们想使用某个特定的库,它将会提供必要的依赖库和包含文件给我们。pkg-config从...
  • gcc编译C代码以及Makefile文件的书写

    千次阅读 2019-04-05 11:29:25
    文章目录一、如何用gcc编译C代码二、如果编写Makefile文件三、在Makefile中使用变量四、Makefile的自动推导特性 一、如何用gcc编译C代码 如果只有单个文件,一般直接执行下面这条命令就可以进行编译了。 执行命令:...
  • Linux gcc编译命令

    万次阅读 2018-11-19 19:40:57
    编译、链接 和运行C程序 编写一个C程序 用 touch 命令:“touch 文件名” 可以创建一个文件(比如 touch hello.c),如下图:
  • Linux下gcc编译生成动态链接库*.so文件并调用它 gcc -c test.c将生成test.o的目标文件 gcc -o app test.c将生成可执行程序app 动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的...
  • 什么是GCC? GCC编译过程

    千次阅读 2018-11-23 23:19:25
    其实一开始的确是这样的,GCC 原名为GUN C 语言编译器( GNU C Compiler), 原本只能处理编译C语言。 但是后来GCC发展壮大了,可以编译C++, Fortran,Pascal,Objective-C, Java,Ada,Go以及各类处理器构架上的汇编语言...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 412,001
精华内容 164,800
关键字:

gcc编译