C/C++/nvcc 预处理、编译、汇编、链接、动态链接库、静态链接库

本文主要总结,C++ 的编译链接以及底层相关概念。

1、编译过程

实际上,C++代码从预处理到执行经历了四个阶段:1)预处理 2)编译 3) 汇编 4) 链接

链接

预处理基本上是宏展开,替换,删除注释,头文件展开的过程。编译-汇编(gcc -c) 主要是将源文件编译成目标文件.o 的过程此时是汇编代码。

  • 这里主要说明链接过程:
    链接器将编译产生的.o 文件链接到一起,产生最后的可执行二进制文件。 人们把源代码的各个模块独立编译,然后按照需要将他们组装起来,这个组装的过程就是Linking

  • 链接的过程主要为:
    地址和空间分配、地址绑定、重定位

  • 举例
    例如在main函数种,使用了模块func.c 中的函数foo(), 因此在main函数的每一个调用foo的地方,都必须给出foo函数的地址。
    但是,编译过程是独立的,因此main不知道foo的函数地址。因此需要将这些调用foo的目标地址搁置。等到链接阶段再将地址修正。
    需要注意的是,func.c 每次被重新编译,foo函数的地址都可能产生变化。
    连接器实际上会根据main函数调用foo,自动的去各个模块种寻找引用的符号foo,然后将main.c 模块种所有引用到foo的指令重新修正。
    上述过程就是静态链接的基本过程。

详细过程

  • 1 编译过程如下:

C/C++/nvcc 预处理、编译、汇编、链接、动态链接库、静态链接库_第1张图片

  • Pre-processing: 通过GNU C 预处理器 cpp,这个可以打开头文件以及进行宏展开

cpp hello.c > hello.i

  • Compilation : 对上述hello.i 进行汇编

gcc -S hello.i

  • Assembly: 汇编器as 将汇编代码转为机器码

as -o hello.o hello.s

  • Linker: 链接器ld 将目标文件与库文件链接成可执行代码hello.exe

ld -o hello.exe hello.o ...libraries...

2、两个重要参数

hello.cpp 如下

#include 
using namespace std;


int main() {
   cout << "Hello, world!" << endl;
   std::cout << ID << std::endl;
   return 0;
}
  • Verbose Mode (-v)
    g++ -v hello.cpp 可以显示比较详细的链接库,包含头文件路径等

  • Defining Macro (-D)
    g++ -DID=12 hello.cpp // -Dname可以将变量的名字传进cpp文件

3、Headers (.h), Static Libraries (.lib, .a) and Shared Library (.dll, .so)

3.1 动态链接库与静态链接库区别

  • A library is a collection of pre-compiled object files that can be linked into your programs via the linker.
  • 动态链接库 Dynamic linking makes executable files smaller and saves disk space, because one copy of a library can be shared between multiple programs. Furthermore, most operating systems allowsone copy of a shared library in memory to be used by all running programs, thus, saving memory. The shared library codes can be upgraded without the need to recompile your program.
  • 静态链接库 the machine code of external functions used in your program is copied into the executable

3.2 头文件与库的搜索规则

  • 通过-I 可以指定头文件搜索目录 -I SearchDir
  • -Ldir 指定库搜索目录,或者指定-lxxx option (lowercase letter ‘l’, without the prefix “lib” and “.a” extension)

cuda代码

#include 

__global__ void hello_from_gpu(void)

{

   printf("Hello World from the GPU!n");

}

int main(void)

{

   hello_from_gpu<<<22, 20>>>();
   //cudaDeviceReset();  //cudaDeviceReset();
   cudaDeviceSynchronize();
   return 0;
}

编译 nvcc test.cu 然后即可运行

nvcc -c -arch sm_60  -std=c++11 roi_align_kernel.cu 
-I /Dev/ptorch_dev/libtorch/include/ -I /Dev/libtorch/include/
g++ -c roi_align_cuda.cpp -std=c++11 -I /Dev/libtorch/include/ 
-I /Dev/libtorch/include/torch/csrc/api/include/
ar -rv libroialign.a roi_align_kernel.o roi_align_cuda.o

Ref:

【1】https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html

你可能感兴趣的:(pytorch,C++,torch7)