C/C++编译过程详解

gcc

将C/C++编译成可执行文件的过程

  1. 预处理,将#开头的指令,如头文件和宏定义进行文本替换,生成预处理后的代码。
  2. 编译:预处理后,gcc将处理后的代码编译成汇编语言代码,生成.s文件。
  3. 汇编:生成的汇编代码被汇编器转换为机器码(二进制指令)的目标文件。
  4. 链接:最后一步是链接,链接器(ld)将编译生成的目标文件与系统库文件和其他必要的目标文件进行链接。

用gcc将test.c进行编译、汇编、链接

  1. 编译
    gcc -c test.c -o test.o
    -c代表只进行除链接外的编译操作
  2. 汇编
    gcc -S test.c -o test.s
    -S代表只进行编译为汇编语言的操作,不进行进一步的汇编和链接。
  3. 链接
    不包含库文件:
    gcc test.o -o test
    调用额外的库文件:
    gcc object1.o object2.o -L/path/to/library -lexample -o executable
    将.o转换为可执行文件。
    平时编译的时候如果不需要中间文件(.s,.o)可以使用gcc直接一步到位生成可执行文件:
    gcc source_file.c -o executable
    链接库:
    gcc source_file.c -L/path/to/library -lname_of_library -o executable
  • source_file.c是源代码文件的名称。
  • -L/path/to/library指定库文件的搜索路径。将/path/to/library替换为实际的库文件所在路径。
  • -lname_of_library指定要链接的库文件的名称。将name_of_library替换为实际的库文件名称,不包括库文件的前缀lib和文件扩展名。
  • -o executable指定生成的可执行文件的名称。

生成库文件

  1. 生成静态库
    ar rcs liblibrary.a library_object1.o library_object2.o
    生成的库名称为:liblibrary.a。
    ar rcs是一个用于创建静态库的命令
  • ar是一个归档工具,用于创建、修改和提取静态库文件
  • r是ar命令的一个选项,表示将文件添加到归档中,如果文件已经存在,则替换原始文件。
  • c是ar命令的一个选项,表示创建一个新的归档文件。
  • s是ar命令的一个选项,表示在归档文件中添加索引(符号表),这样可以加快链接时的符号解析速度。
    综合起来,ar rcs命令的作用是创建一个新的静态库文件,并向其中添加目标文件。如果库文件已经存在,则替换原始文件。此命令还会在归档文件中添加索引,以提高链接时的符号解析效率。
  1. 生成动态库
    gcc -shared -o liblibrary.so library_object1.o library_object2.o
    生成的库名称为:liblibrary.so
    -shared:是GCC的一个选项,指示编译器生成一个共享库(动态库)。这个选项告诉编译器不要将目标文件与其他目标文件进行链接,而是生成一个独立的共享库文件。
    在还没生成.o文件之前,编译源文件为目标文件:
    gcc -c -fPIC source1.c source2.c -o object1.o object2.o
    -fPIC:是GCC的一个选项,表示生成位置无关代码(Position Independent Code)。这个选项通常在编译共享库(动态库)时使用,以确保库可以在内存中的任何位置加载和运行。

make

简单makefile示例

CC := gcc
CFLAGS := -Wall -Wextra

SRCDIR := src
BUILDDIR := build
TARGET := myapp

SOURCES := $(wildcard $(SRCDIR)/*.c)
OBJECTS := $(patsubst $(SRCDIR)/%.c,$(BUILDDIR)/%.o,$(SOURCES))

$(TARGET): $(OBJECTS)
    $(CC) $^ -o $@

$(BUILDDIR)/%.o: $(SRCDIR)/%.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -rf $(BUILDDIR)/* $(TARGET)