gcc
2020-02-18 本文已影响0人
oasis_m
声明:所有文章只作为学习笔记用,转载非原创
ldd /bin/ls
https://www.cnblogs.com/SoaringLee/p/10532414.html
https://blog.csdn.net/qq_23599965/article/details/90520835
objdump -T /lib64/libselinux.so.1
//打开当前目录下的动态链接库libmysqlclient.so查看其中的API。objdump命令用来查看各种目标文件(elf文件)内部的结构
obidump -h hello.o //参数-h把hello.o各个段的基本信息打印出来,elf文件是分段的,通常分为Header、.data(数据段包括局部静态变量和全局变量)、.text(代码段)、.rodata、.bss、.comment等
readelf -s hello.o //查看详尽段信息
gcc错误:undefined reference to function 该函数具体实现没有找到
info gcc //显示gcc的所有信息
从程序员的角度看,函数库实际上就是一些头文件(.h)和库文件(.so或者.a)的集合。
虽然 Linux 下的大多数函数都默认将头文件放到 /usr/include/ 目录下,而库文件则放到 /usr/lib/
目录下,但并不是所有的情况都是这样。正因如此, GCC 在编译时必须有自己的办法来查找所需要的头文件和库文件, GCC 采用搜索目录的办法来查找所需要的文件。
库是一组预先编译好的函数的集合,这些函数都是按照可重用的原则编写的。
预处理 ----> 编译 ----> 汇编 ----> 链接
[https://www.cnblogs.com/wanglijun/p/8637592.html](https://www.cnblogs.com/wanglijun/p/8637592.html)
预处理( Pre-Processing )
编译( Compiling )
汇编( Assembling )
链接( Linking )
1 Linux 程序员可以根据自己的需要让 GCC 在编译的任何阶段结束,以便检查或使用编译器在该阶段的输出信息,或者对最后生成的二进制文件进行控制,以便通过加入不同数量和种类的调试代码来为今后的调试做好准备。和其它常用的编译器一样, GCC 也提供了灵活而强大的代码优化功能,利用它可以生成执行效率更高的代码。
2 GCC 提供了 30 多条警告信息和 3 个警告级别,使用它们有助于增强程序的稳定性和可移植性。此外, GCC 还对标准的 C 和 C++ 语言进行了大量的扩展,提高程序的执行效率,有助于编译器进行代码优化,能够减轻编程的工作量。
3 从程序员的角度看,函数库实际上就是一些头文件(.h)和库文件(.so或者.a)的集合。
GCC编译过程
gcc 预处理阶段:主要对包含的头文件(#include)和宏定义(#define、#ifdef …)进行处理。可以使用“gcc -E” 让 gcc 在预处理之后停止编译过程,生成 *.i 文件:
gcc -E hello.c -o hello.i
1
gcc 编译阶段:gcc 首先要检查代码的规范性,是否有语法错误等。以确定代码实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。用户可以使用-S选项进行查看,该选项只进行编译而不进行汇编,生成汇编代码:
gcc -S hello.i -o hello.s
1
gcc 汇编阶段:生成目标代码 *.o ;有两种方式:使用 gcc 直接从源代码生成目标代码 gcc -c *.s -o *.o 以及使用汇编器从汇编代码生成目标代码 as *.s -o *.o:
gcc -c hello.s -o hello.o
as hello.s -o hello.o
1
2
也可以直接使用as *.s, 将执行汇编、链接过程生成可执行文件a.out, 可以像上面使用-o选项指定输出文件的格式。
gcc 链接阶段:生成可执行文件;可以生成的可执行文件格式有:a.out/*/,当然可能还有其它格式。
gcc hello.o 生成可执行文件 a.out
gcc hello.o -o hello 生成可执行文件 hello
[https://www.cnblogs.com/wanglijun/p/8637592.html](https://www.cnblogs.com/wanglijun/p/8637592.html)
[https://blog.csdn.net/hou09tian/article/details/90290264](https://blog.csdn.net/hou09tian/article/details/90290264)
理论概述:
.h中一般放的是同名.c文件中定义的变量、数组、函数的声明,需要让.c外部使用的声明。
1)h文件作用:
1.方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明;
2. 使函数的作用域从函数声明的位置开始,而不是函数定义的位置(实践总结)
3 .提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h)。
[https://www.cnblogs.com/jpfss/p/10001012.html](https://www.cnblogs.com/jpfss/p/10001012.html)
[https://www.cnblogs.com/notorious/p/10618788.html](https://www.cnblogs.com/notorious/p/10618788.html)
注意到开头结尾的预编译语句。在头文件里,并不写出函数的具体实现
一个头文件:s.h
#ifndef _MY_SO_HEADER_
#define _MY_SO_HEADER_
void out_msg(const char *m);
#endif </pre>
再来一个C文件来引用这个库中的函数:ts.c
#include <stdio.h>
#include "s.h"
int main(int argc, char** argv)
{
printf("TS Main\n");
out_msg("TS ");
sleep(5); //这句话可以注释掉,在第4节的时候打开就可以。
printf("TS Quit\n");
} </pre>