GCC/CLANG编译器


GCC是在linux下使用的编译器,Clang是在mac上使用的编译器,二者的命令几乎同样
本文运行环境为mac

编译指令

gcc/clang -g -O2 -o test test.c -I... -L... -l...

-g 输出文件中的调试信息
-O 大写的O,对输出文件作指令优化,2表示对文件进行第二个级别的编译优化,更完全,若是调试的话,则不须要-O
-o 输出文件
-I 指定头文件位置,使用第三方库或者本身建立,
-L 指定lib库位置
-l 意为link,指定使用哪一个库,不必定全部都用html

编译过程

vim main.c
建立一个main函数文件,c程序必须以main函数为入口点linux

# include <stdio.h>
 
int main()
{
    printf("hello world\n")return 0;
}

预处理

gcc -E main.c -o main.i

-E 表示生成预处理文件web

具体内容:vim

  1. 宏定义指令 #define xxxx
  2. 条件编译 #if #else #endif…
  3. 头文件包含指令 #include 将头文件和源代码拷贝到一块儿
  4. 特殊符号处理 例如对方法参数中的空格处理

常见问题:
不能在头文件中定义全局变量,由于在头文件中定义全局变量将会使全部包含该头文件的文件存在该段代码,也就是说这些文件将定义一个相同的全局变量,这样将不可避免的形成冲突架构

首先对源文件进行预处理,这个过程主要是处理一些#号定义的命令或语句(如宏、#include、预编译指令#ifdef等),生成*.i文件。即绑定头文件和宏断定等操做,将头文件和源代码拷贝到一块儿,以便编译器进行编译iphone

编译

gcc -S main.i -o main.s

-S 让编译程序在生成汇编语言输出svg

具体内容:
编译环节是指对源代码进行语法分析,并优化产生对应的汇编代码的过程,经过词法分析和语法分析,将其翻译成等价的中间代码或汇编代码。局部优化、控制流分析和循环优化、数据流的分析和全局优化。函数

进行词法分析、语法分析和语义分析等,生成*.s的汇编文件优化

汇编

gcc -c main.s -o main.o

-c 表示编译、汇编指定的源文件(也就是编译源文件),可是不进行连接spa

将对应的汇编指令翻译成机器指令,生成可重定位的二进制目标文件.o

连接

vi add.c 建立一个add方法文件

#ifndef __MY_LIBRARY__
#define __MY_LIBRARY__
int add(int a, int b){
return (a+b);
}
#endif 

而后编译,并使用libtool,生成一个静态库包含add.o

gensees-iMac:study gensee$ vi add.c
gensees-iMac:study gensee$ clang -g -c add.c
gensees-iMac:study gensee$ ls add.o
add.o
gensees-iMac:study gensee$ ./add.o
gensees-iMac:study gensee$ libtool -static -o libmylib.a add.o

生成了一个lib文件
在这里插入图片描述
Ex : 这里使用ar命令能够查看静态库的组成

gensees-iMac:study gensee$ ar -t /Users/gensee/Desktop/study/libmylib.a 
__.SYMDEF SORTED
add.o

ar是linux命令,更多查看 https://www.runoob.com/linux/linux-comm-ar.html

建立一个main函数文件 main.c,并编译为.o

#include <stdio.h>
#include "add.h" 
int main()
{
   int sum = add(1,5);
   printf("%d\n",sum);
   return 0;
}
clang -g -c main.c

这里一样咱们也须要建立一个add.h头文件以便引用
使用vi add.h

#ifndef __MY_LIBRARY__
#define __MY_LIBRARY__
int add(int a, int b);
#endif 

而后咱们进行连接

clang -o main main.o -L . -lmylib
gensees-iMac:study gensee$  clang -o main main.o -L . -lmylib
gensees-iMac:study gensee$ ./main
6
gensees-iMac:study gensee$

能够看到最后执行了add方法结果为6

一步执行方法

前提是编译好mylib

clang -g -o main mian.c -I . -L . -lmylib

-I . 表示当前目录头文件
-L . 表示当前目录lib

gensees-iMac:study gensee$  clang -g -o main main.c -I . -L . -lmylib
gensees-iMac:study gensee$ ./main
6
gensees-iMac:study gensee$

连接方式

连接系统的库,三方库,分为动态连接和静态连接

静态连接和动态连接二者最大的区别就在于连接的时机不同,静态连接是在造成可执行程序前,而动态连接的进行则是在程序执行时。

静态连接:将源文件中用到的库函数与汇编生成的目标文件.o合并生成可执行文。每个可执行程序对全部须要的目标文件有一份副本,浪费空间,并且更新须要从新编译造成可执行程序。
动态连接:解决了静态连接浪费空间,更新困难的问题,只须要加载一次,存在内存中,每一个程序均可以使用。

指令查看网址:http://c.biancheng.net/view/2375.html

将OC反编译为C

将.m编译为cpp

clang -rewrite-objc main.m -o test.cpp

指定架构

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o testMain.cpp