Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 Linux 版本下不兼容的问题; 2)在 Linux 静态库的制作过程中发现有别于 Windows 下静态库的制作方法;3)在 Linux 应用程序链接第三方库或者其他静态库的时候发现链接顺序的烦人问题。本文这三个问题针对 Linux 下标准库链接和如何巧妙构建 achrive(*.a) 展开相关介绍。
  两个要知道的基本知识
  Linux 应用程序因为 Linux 版本的众多与各自独立性,在工程制作与使用中必须熟练掌握如下两点才能有效地工作和理想地运行。
  1、Linux 下标准库链接的三种方式(全静态 , 半静态 (libgcc,libstdc++), 全动态)及其各自利弊。
  2、Linux 下如何巧妙构建 achrive(*.a),并且如何设置链接选项来解决 gcc 比较特别的链接库的顺序问题。
  三种标准库链接方式选项及对比
  为了演示三种不同的标准库链接方式对终应用程序产生的区别, 这里用了一个经典的示例应用程序 HelloWorld 做演示,见 清单 1 HelloWorld。
  清单 1. HelloWorld
#include <stdio.h>
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char* argv[])
{
printf("HelloWorld!(Printed by printf) ");
cout<<"HelloWorld!(Printed by cout)"<<endl;
return 0;
}
  三种标准库链接方式的选项及区别见 表 1

  上述三种标准库链接方式中,比较特殊的是 半静态链接方式,主要在于其还需要在链接前增加额外的一个步骤:
  ln -s g++ -print-file-name=libstdc++.a,作用是将 libstdc++.a(libstdc++ 的静态库)符号链接到本地工程链接目录。
  -print-file-name 在 gcc 中的解释如下:
  -print-file-name=<lib> Display the full path to library <lib>
  为了区分三种不同的标准库链接方式对终生成的可执行文件的影响,本文从两个不同的维度进行分析比较:
  维度一:终生成的可执行文件对标准库的依赖方式(使用 ldd 命令进行分析)
  ldd 简介:该命令用于打印出某个应用程序或者动态库所依赖的动态库
  涉及语法:ldd [OPTION]… FILE…
  其他详细说明请参阅 man 说明。
  三种标准库链接方式终产生的应用程序的可执行文件对于标准库的依赖方式具体差异见 图 1、图 2、图 3所示:

  通过上述三图,可以清楚的看到,当用 全静态标准库的链接方式时,所生成的可执行文件终不依赖任何的动态标准库,
  而 全动态标准库的链接方式会导致终应用程序可执行文件依赖于所有用到的标准动态库。
  区别于上述两种方式的 半静态链接方式则有针对性的将 libgcc 和 libstdc++ 两个标准库非动态链接。
  (对比 图 2与 图 3,可见在 图 3中这两个标准库的动态依赖不见了)
  从实际应用当中发现,理想的标准库链接方式是半静态链接,通常会选择将 libgcc 与 libstdc++ 这两个标准库静态链接,
  从而避免应用程序在不同 Linux 版本间标准库依赖不兼容的问题发生。
  维度二 : 终生成的可执行文件大小(使用 size 命令进行分析)
  size 简介:该命令用于显示出可执行文件的大小
  涉及语法:size objfile…
  其他详细说明请参阅 man 说明。
  三种标准库链接方式终产生的应用程序的可执行文件的大小具体差异见 图 4、图 5、图 6所示:

  通过上述三图可以看出,终可执行文件的大小随终所依赖的标准动态库的数量增加而减小。
  从实际应用当中发现,理想的是 半静态链接方式,因为该方式能够在避免应用程序于
  不同 Linux 版本间标准库依赖不兼容的问题发生的同时,使终生成的可执行文件大小小化。
  示例链接选项中所涉及命令(引用 GCC 原文):
  -llibrary
  -l library:指定所需要的额外库
  -Ldir:指定库搜索路径
  -static:静态链接所有库
  -static-libgcc:静态链接 gcc 库
  -static-libstdc++:静态链接 c++ 库
  关于上述命令的详细说明,请参阅 GCC 技术手册