编译琐事

  • 当编译一个可执行文件时,如果声明了一个函数却没有定义,则:
    • 假如代码用到了这个函数,会报错:undefine reference
    • 假如代码没用到这个函数,不会报错,但编译后的结果的符号表里不含这个函数的符号。
  • 对于静态库和动态库,如果声明了一个函数却没有定义,则无论代码是否用到了这个函数,都不会报错,但编译后的结果的符号表里该符号为"U"(未定义);对于动态库,可以使用-Wl,--no-undefined选项让链接阶段强制保证所有的符号都是定义的。
  • 当编译可执行文件时,如果可执行文件用到了动态库中定义的函数,如果连接的过程中找到了相关的定义,则能够正常编译,但是符号表里会标记为"U";如果没有找到,则会报错,终止编译。
  • 静态库只是目标文件的集合。
  • 编译静态库时没有链接的过程,因而静态库不包含它的依赖。
  • 动态库只能依赖使用-fPIC选项编译的静态库,链接过程会将其链接进本身。
  • PIC(Position Indepedent Code)会产生地址无关符号表,方便动态库被动态加载和复用。
  • 动态库依赖动态库时,并不会将其链接进本身。
  • 动态库编译时的搜索顺序,运行时的搜索顺序。
  • 预处理器对include的搜索顺序。(可以在预处理时使用-v选项查看)
  • 交叉编译工具链。
  • 交叉编译的SYSROOT是为了营造一个目标环境的文件系统,通常会有$SYSROOT/usr等路径。
  • 对于CMAKE来说,应当为交叉编译相关的选项建立toolchain文件,并通过CMAKE_TOOLCHAIN_FILE选项传入。
  • 交叉编译时有CMAKE_FIND_ROOT_PATH变量,是用于find_*命令,同时可以用CMAKE_FIND_ROOT_PATH_MODE_*来控制为ONLY还是NEVER级别。
  • 应用程序二进制接口ABI的概念。
  • 嵌入式应用程序二进制接口EABI的概念。
  • 使用不同的编译器编译出来的静态库一定不能通用,动态库可能能通用。

你可能感兴趣的:(编译琐事)