linux开发之gcc与g++区别,静态库、动态库

gcc

广义上指GNU编译器套装(英语:GNU Compiler Collection,缩写为GCC)是GNU计划制作的一种优化编译器,支持各种编程语言、操作系统、计算机系统结构。

狭义上指GNU C语言编译器(GNU C Compiler)。

常用gcc/g++参数。

编译选项 说明
-E 预处理指定文件,不进行编译
-S 编译指定文件,不进行汇编
-c 编译汇编指定文件,不进行链接
-o [filename] 令生成文件名为filename
-I 目录 指定include包含文件的搜索目录
-g 编译时候附带调试信息
-D 编译时指定一个宏
-w 不生成任何警告信息
-Wall 生成所有警告信息
-On n取值[0,3]。编译器优化的4个级别。0表示不进行优化,1为默认值,3为最高级别
-l 在程序编译时候指定使用的库
-L 在程序编译时使用的库的搜索路径
-fpic/fPIC 生成与为止无关代码(一般用于动态库
-shared 生成共享目标文件,建立动态库
-std 指定标准版本

gcc 与 g++区别

我们一般在编译c语言用的是gcc,编译c++用的是g++。但其实gcc也可以编译c++程序,只不过链接时候缺少c++库。可以通过参数指定成功链接。

假设我们有如下代码文件acpp.cpp

#include <iostream>
int main() {
    std::cout << "I'm a cpp program\n";
    return 0;
}

如图为gcc编译链接c++代码不指定c++库。可以看到链接失败。
gcc编译链接不指定库

如图为gcc只编译c++代码。可以看到,成功编译。
gcc只编译连接c++代码

如图为gcc编译链接c++代码并指定库。可以看到,成功编译链接,能够正常执行程序。
gcc编译链接c++代码并指定库

当然可以gcc编译cpp代码后,用g++去链接。其实本质上,g++编译c++代码同样是调用gcc去编译的。

方便来说,其实就是用gcc去编译连接c语言,g++去编译连接c++语言。只不过两者并不是互相不通的,而是联系紧密。

静态库、动态库

当分发代码时候,可以使用静态库、动态库。

操作系统 文件名
静态库 linux libxxx.a
静态库 windows libxxx.lib
动态库 linux libxxx.so
动态库 Windows libxxx.dll

注意:xxx是库的名字,libxxx.a等是库的文件的名字。

静态库的使用方式是链接时候,将代码插入带可执行程序中融为一体。动态库的使用方式是,当程序运行时,将动态库加载到内存中供程序调用。

假设我们有如下代码文件。head.h中包含了add函数的声明。

// a.cpp
int add(int a, int b) {
    return a + b;
}
// test.cpp
#include <iostream>
#include "head.h"
using namespace std;
int main() {
    cout << "Hello World" << endl;
    printf("a + b = %d\n", add(1, 3));
    return 0;
}

静态库

制作

目标是将a.cpp的内容制作成静态库,静态库名为aaa。

步骤为先用g++生成其目标文件,再用ar rcs libxxx.a 目标文件1 目标文件2...将其打包成为静态库。
制作静态库

使用

编译时指定库名称-l库名称,并且指定库的搜索路径-L路径
使用静态库

动态库

制作

目标是将a.cpp的内容制作成动态库,动态库名为aaa。

步骤为先用g++生成其目标文件(参数-fpic),再用g++ -shared 目标文件1 目标文件2... -o libxxx.so生成动态库。
制作动态库

使用

编译时指定库名称-l库名称,并且指定库的搜索路径-L路径
使用动态库

然而,当动态库不和可执行文件在同一目录下时,会出现问题。
执行失败

其原因是,无法找到动态库的位置,解决方法大概分为4种:

  • 修改程序的DT_RPATH段(不推荐
  • 修改环境变量LD_LIBRARY_PATH
  • 修改 /etc/ld.so.cache文件列表
  • 复制到/lib/或/usr/lib/目录下(不推荐

修改环境变量LD_LIBRARY_PATH

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ubuntu/nccourse/lesson-3/lib

成功执行

修改 /etc/ld.so.cache文件列表:

修改/etc/ld.so.conf,然后ldconfig来个更新/etc/ld.so.cache。

修改

内容

更新后成功运行

posted @ 2023-04-12 20:21  1v7w  阅读(161)  评论(0编辑  收藏  举报