前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux/C++】Linux下C++命令行编译示例

【Linux/C++】Linux下C++命令行编译示例

作者头像
极客开发者
发布2022-01-18 14:25:26
2.1K0
发布2022-01-18 14:25:26
举报
文章被收录于专栏:极客开发者

此文档是在Linux下C/C++开发的g++编译示例,如果继续阅读此文,并希望有所收获,你应当具备以下技能

  • C++编程语言基础
  • Linux系统操作基础

文章目录

代码语言:javascript
复制
1. 准备源代码
2. 编译实战
   2.1. 引入目录进行编译
   2.2. 使用-Wall、-std 参数进行编译
   2.1.3. 生成库文件
       链接静态库生成可执行文件
       链接动态库生成可执行文件
       静态库和动态库生成可执行文件的区别

这是这个系列的第2篇文章,你可以通过以下链接阅读第一篇

1. Linux中编译C++代码的g++工具,以及g++的常用操作指令

1. 准备源代码

在一个工作目录中创建以下代码文件,目录结构如下图

代码内容如下:

swap.h文件,这个源码文件中定义了C++头部信息

代码语言:javascript
复制
#include <iostream>
using namespace std;

swap.cpp文件,这个文件中定义了我们将在主函数中调用的C++代码

代码语言:javascript
复制
#include "swap.h"

void swap(int &a, int &b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

main.cpp文件,这是主函数文件,函数调用的入口

代码语言:javascript
复制
#include <iostream>
#include "swap.h"
using namespace std;

int main(int argc, char const *argv[])
{
    int val1 = 10;
    int val2 = 20;

    cout << " Before swap:" << endl;
    cout << " val1:" << val1 << endl;
    cout << " val2:" << val2 << endl;

    swap(val1, val2);

    cout << " After swap:" << endl;
    cout << " val1:" << val1 << endl;
    cout << " val2:" << val2 << endl;

    return 0;
}

2. 编译实战

2.1. 引入目录进行编译

直接编译

代码语言:javascript
复制
g++ main.cpp src/swap.cpp

此时会看到如下图的错误

这是因为 g++ 找不到include目录下的swap.h 文件,所以我们需要使用-I参数将include目录包含进来,如下命令

代码语言:javascript
复制
g++ main.cpp src/swap.cpp -Iinclude

这时候代码就可以顺便通过编译了。

2.2. 使用-Wall、-std 参数进行编译

-Wall 代表程序编译过程中输出警告信息,-std代表使用特定的 c++标准 进行编译,如下命令

代码语言:javascript
复制
# 使用c++11标准进行编译,并且使用-Wall参数
g++ main.cpp src/swap.cpp -Iinclude -Wall -std=c++11 -o a.out

此时我们看到,还是能正常编译,也没有输出警告,我们也可以正常执行a.out。因为我们的代码是符合c++11标准的,为了演示一个警告,我们在main.cpp中加一行代码。如下

代码语言:javascript
复制
#include <iostream>
#include "swap.h"
using namespace std;

int main(int argc, char const *argv[])
{
    int val1 = 10;
    int val2 = 20;
    // 定义一个变量,但是不使用
    double d = 0.0;

    cout << " Before swap:" << endl;
    cout << " val1:" << val1 << endl;
    cout << " val2:" << val2 << endl;

    swap(val1, val2);

    cout << " After swap:" << endl;
    cout << " val1:" << val1 << endl;
    cout << " val2:" << val2 << endl;

    return 0;
}

把输出文件改为b.out,再次执行编译,如下命令

代码语言:javascript
复制
g++ main.cpp src/swap.cpp -Iinclude -Wall -std=c++11 -o b.out

此时出现如下图警告

因为定义一个变量不使用,是不符合c++11的标准的,但不是错误,b.out也能正常执行。

2.1.3. 生成库文件

我们先删除在 2 中会进行警告的代码

链接静态库生成可执行文件

代码语言:javascript
复制
# 先进入src目录
cd  src
# 汇编生成swap.o 文件
g++ swap.cpp -c -I../include
# 生成静态库libSwap.o
ar rs libswap.a swap.o
# 回到代码根目录,调用静态链接库生成可执行文件
g++ main.cpp -lswap -Lsrc -Iinclude -o static_main

链接动态库生成可执行文件

代码语言:javascript
复制
# 进入src目录
cd  src
# 生成动态链库文件libswap.so
g++ swap.cpp -I../include -fPIC -shared -o libswap.so
# 上面的指令等价于下面两条指令
# gcc swap -I../include -c -fPIC
# gcc -shared -o libswap.so swap.o

# 回到上级目录
cd ..
# 链接生成可执行文件 dyna_main
g++ main.cpp -Iinclude -lswap -Lsrc -o dyna_main

静态库和动态库生成可执行文件的区别

  • 静态库在打包生成二进制文件的时候,直接将静态库包含进来
  • 动态库则在打包时不打包库文件,而在运行时再把动态库文件引进来

所以我们运行的时候,静态库文件打包的可执行文件可以直接运行。而用动态库编译生成的可执行文件,直接运行会报错,是因为动态链接文件在我们的代码目录,并不在系统的库搜索目录。如果要运行动态链接库打包生成的可执行文件,我们需要手动指定程序运行依赖的库目录。

运行可执行文件命令如下:

运行静态打包的可执行文件

代码语言:javascript
复制
# 运行静态打包的可执行文件
./static_main

运行动态链接库打包生成的可执行文件

代码语言:javascript
复制
# 运行动态打包的可执行文件,需要设置 LD_LIBRARY_PATH 变量,变量值是动态链接文件所在目录
LD_LIBRARY_PATH=src ./dyna_main
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客开发者up 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 准备源代码
  • 2. 编译实战
    • 2.1. 引入目录进行编译
      • 2.2. 使用-Wall、-std 参数进行编译
        • 2.1.3. 生成库文件
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档