gcc 编译器使用指南

目录

  • 安装
  • 准备test.cpp
  • 编译
  • g++ 编译参数
    • -g :编译带调试信息的可执行文件
    • -O[n] :开启优化
    • -l 和 -L :指定库文件 | 指定库文件路径
    • -I :指定头文件搜索目录
    • -Wall 和 -w:打印警告信息 | 关闭警告信息
    • -std=c++11 :设置编译标准
    • -o :指定输出文件名
    • -D :定义宏
  • 实例演示
    • 直接编译
    • 生成库文件并编译

参考:
https://b23.tv/tWqKrC
我的linux版本如下:
Linux version 5.4.0-88-generic (buildd@lgw01-amd64-008) (gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04))
使用命令:

cat /proc/version

即可查看

安装

sudo apt update
# 安装编译器和调试器
sudo apt install build-essential gdb
# 安装完成后,确认是否成功
gcc --version
g++ --version
gdb --version

准备test.cpp

mkdir test
cd test
touch test.cpp
vim test.cpp
# 设置tab缩进
:set tabstop=4

然后写代码:

#include<iostream>
using namespace std;
int main()
{cout << "test" << endl;return 0;
}

编译

在实际使用中,使用gcc指令编译c代码,g++指令编译c++代码。
一般cpp文件需要通过四个过程生成可执行文件:
预处理、编译、汇编、链接

# 预处理 .cpp -> .i
# -E 表示编译器只对输入文件进行预处理
g++ -E test.cpp -o test.i
# 编译 .i -> .s
# -S 表示在c++代码产生了汇编语言文件后停止编译,产生的汇编语言文件为 .s
g++ -S test.i -o test.s
#  汇编 .s -> .o
# -c g++仅把源代码编译为机器语言的目标代码
g++ -c test.s -o test.o
# 链接 .o -> bin文件
# -o 为将来产生的可执行文件用指定的文件名
g++ test.o -o test 

以上的步骤也可以直接用一个步骤代替:

g++ test.cpp -o test

现在test文件夹里面是这样:

drwxrwxrwx 2 dyy dyy  4096 1019 14:44 ./
drwxrwxrwx 8 777 dyy  4096 1019 13:54 ../
-rwxrwxr-x 1 dyy dyy 17320 1019 14:44 test*
-rw-rw-r-- 1 dyy dyy    91 1019 14:38 test.cpp

运行它: 成功

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/test$ ./test 
test

g++ 编译参数

-g :编译带调试信息的可执行文件

# -g 选项告诉 GCC 产生能被 GNU 调试器GDB使用的调试信息,以调试程序。
g++ -g test.cpp

-O[n] :开启优化

# -O 选项告诉 g++ 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。 -
# -O0 表示不做优化
# -O1 为默认优化
# -O2 除了完成-O1的优化之外,还进行一些额外的调整工作,如指令调整等。
# -O3 则包括循环展开和其他一些与处理特性相关的优化工作。
g++ -O2 test.cpp

-l 和 -L :指定库文件 | 指定库文件路径

# -l参数(小写)就是用来指定程序要链接的库,-l参数紧接着就是库名
# 在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接# 链接glog库
g++ -lglog test.cpp# 如果库文件没放在上面三个目录里,需要使用-L参数(大写)指定库文件所在目录
# -L参数跟着的是库文件所在的目录名
# 链接mytest库,libmytest.so在/home/bing/mytestlibfolder目录下
g++ -L/home/bing/mytestlibfolder -lmytest test.cpp

-I :指定头文件搜索目录

# -I
# /usr/include目录一般是不用指定的,gcc知道去那里找,但 是如果头文件不在/usr/icnclude
# 里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-
# I/myinclude 参数了,如果不加你会得到一个”xxxx.h: No such file or directory”的错
# 误。-I参数可以用相对路径,比如头文件在当前 目录,可以用-I.来指定。上面我们提到的–cflags参
# 数就是用来生成-I参数的。
g++ -I/myinclude test.cpp

-Wall 和 -w:打印警告信息 | 关闭警告信息

# 打印出gcc提供的警告信息
g++ -Wall test.cpp
# 关闭警告信息
g++ -w test.cpp

-std=c++11 :设置编译标准

# 使用c++11的标准编译 test.cpp
g++ -std=c++11 test.cpp

-o :指定输出文件名

# 若不指定,生成文件为a.out
g++ test.cpp -o test

-D :定义宏

# 常用场景:
# -DDEBUG 定义DEBUG宏,可能文件中有DEBUG宏部分的相关信息,用个DDEBUG来选择开启或关闭
# DEBUG
g++ -DDEBUG debugTest.cpp -o debugTest

比如:

#include<stdio.h>
using namespace std;
int main()
{#ifdef DEBUGprintf("DEBUG LOG\n");#endifprintf("in\n");
}

我们编译运行:

g++ -DDEBUG debugTest.cpp -o debugTest
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/test$ ./debugTest 
DEBUG LOG
in

实例演示

test项目录如下:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│   └── swap.h
├── main.cpp
└── src└── swap.cpp2 directories, 3 files

main.cpp内容

#include<iostream>
#include<swap.h>
using namespace std;
int main()
{int val1 = 10;int val2 = 20;cout << "before" << endl;cout << val1 << " " << val2 << endl;swap(val1, val2);cout << "after" << endl;cout << val1 << " " << val2 <<endl;return 0; 
}

swap.h内容

#ifndef _swap_h_
#define _swap_h_
#include<stdio.h>
void swap(int& a, int& b);
#endif

swap.cpp内容

#include"swap.h"
void swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}    

直接编译

最简单编译运行

# 将 main.cpp src/Swap.cpp 编译为可执行文件
g++ main.cpp src/Swap.cpp -Iinclude
# 运行可执行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./a.out 
before
10 20
after
20 10

增加编译参数运行

g++ main.cpp src/swap.cpp -Iinclude -std=c++11 -O2 -Wall -o b.out

生成库文件并编译

首先尝试生成静态库

cd src
# 汇编,生成swap.o文件
g++ swap.cpp -c -I../include
# 生成静态库libswap.a
ar rs libswap.a swap.o
cd ..
# 链接 生成可执行文件staticmain
g++ main.cpp -Iinclude -Lsrc -lswap -o staticmain

现在观察一下项目文件:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│   └── swap.h
├── main.cpp
├── src
│   ├── libswap.a
│   ├── swap.cpp
│   └── swap.o
└── staticmain2 directories, 6 files
dyy@dyy-Lenovo-ThinkBo

现在尝试动态链接

cd src
# 生成动态库
g++ swap.cpp -I../include -fPIC -shared -o libswap.so
# 上面的命令等同于以下两条合起来:
# g++ swap.cpp -I../include -c -fPIC
# g++ -shared -o libswap.so swap.o
cd ..
# 链接,生成可执行文件
g++ main.cpp -Iinclude -Lsrc -lswap -o sharemain

现在观察一下项目文件:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│   └── swap.h
├── main.cpp
├── sharemain
├── src
│   ├── libswap.a
│   ├── libswap.so
│   ├── swap.cpp
│   └── swap.o
└── staticmain

运行可执行文件

# 运行静态链接的可执行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./staticmain 
before
10 20
after
20 10
# 运行含有动态链接的可执行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./sharemain 
./sharemain: error while loading shared libraries: libswap.so: cannot open shared object file: No such file or directory
# 指定一下动态库目录然后再运行
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ LD_LIBRARY_PATH=src ./sharemain 
before
10 20
after
20 10

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bug found:定义对象时

看下面代码 class Test{ }; class Test2{public:Test2(Test *t){}};int main(){Test test();//把定义一个对象 “Test test;” 写成 “Test test();”函数声明了&#xff01;Test2 test2(&test);//return 0;}Dev-cpp的提示信息&#xff1a; no matching function for c…

CMake学习使用(基于vscode)

目录语法一些重要指令CMake常用变量CMake编译工程编译流程两种构建方式实例展示参考&#xff1a; 基于VSCode和CMake实现C/C开发 | Linux篇 语法 基本语法格式&#xff1a;指令(arg1 arg2 …) 参数使用括弧括起来参数之间使用空格或者分号分开 指令是大小写无关的&#xff0…

idhttp.post方式 调用datasnap rest 远程方法

idhttp.get方式调用&#xff0c;这种比较简单&#xff0c;大家都会。post方式网上却没有任何成功的代码&#xff0c;本人也是摸索了一个上午才搞定。 分享给大家。 &#xff08;1&#xff09;post方式调用的远程方法&#xff0c;方法名必须加“update”前缀&#xff0c;不加行不…

[转]连接excel数据源时,首行包含列名称选项在连接字符串中的设置。

关于Excel导入的HDRYES; IMEX1详解 ProviderMicrosoft.Jet.OLEDB.4.0;Data Source111.xls;Extended Properties"Excel 8.0;HDRNO"; 其中HDRNO或YES即首行包含列名称选项 (参数HDR的值&#xff1a;HDRYes&#xff0c;这代表第一行是标题&#xff0c;不做为数据使用&am…

C++多线程快速入门(一):基本常用操作

目录case1&#xff1a;创建线程1 join、detachcase2&#xff1a;创建线程2 线程传参 传值或者传引用case3&#xff1a;创建线程 线程传参 functional object作为参数case4&#xff1a;观察多线程程序加速计算case5&#xff1a;future get 获取并发结果case6&#xff1a;互斥锁…

android:configChanges属性总结

原文地址&#xff1a;http://blog.csdn.net/zhaokaiqiang1992/article/details/19921703 android中的组件Activity在manifest.xml文件中可以指定参数android&#xff1a;ConfigChanges&#xff0c;用于捕获手机状态的改变。 在Activity中添加了android:configChanges属性&#…

eclipse 中修改 M2_REPO的值

从eclipse中增加了maven2的插件之后&#xff0c;maven默认的本地库的路径是${user}/.m2/repository/下&#xff0c;一般windows用户的操作系统都安装在C盘&#xff0c;所以这个目录 下的jar包比较危险。我尝试从myeclipse->preferences->java->build path->classpa…

C++多线程快速入门(二)共享数据同步以及数据竞争

目录std::unique_lock类模板仅调用一次线程局部存储原子变量往期内容回顾std::unique_lock类模板 互斥锁保证了线程间的同步&#xff0c;却将并行操作变成了串行操作&#xff0c;对性能有较大影响&#xff0c;所以我们要尽可能减小锁的区间粒度。 lock_guard只能保证在析构的时…

DNS安全浅议、域名A记录(ANAME),MX记录,CNAME记录

相关学习资料 http://baike.baidu.com/link?url77B3BYIuVsB3MpK1nOQXI-JbS-AP5MvREzSnnedU7F9_G8l_Kvbkt_O2gKqFw7vm http://www.rfc-editor.org/rfc/rfc1035.txt http://www.rfc-editor.org/rfc/rfc3596.txt http://www.rfc-editor.org/rfc/rfc2782.txt http://www.rfc-edito…

ThinkInJava4读书笔记之第一章对象入门

那句话怎么说来着&#xff0c;原句记不住了好像是出来混的迟早要还的。话说当初学校刚开Java课程&#xff0c;自己没有好好学啊&#xff0c;后来直接做了jsp和servlet&#xff0c;然后学了SSH框架和Extjs、jQuery&#xff0c;接着是mybatis&#xff08;ibatis&#xff09;、fre…

C++多线程快速入门(三):生产者消费者模型与条件变量使用

互斥锁完成 #include <iostream> #include <deque> #include <thread> #include <mutex>std::deque<int> q; std::mutex mtx;static void produce(int val) {while(val--) {std::unique_lock<std::mutex> guard(mtx);q.push_front(val);m…

【blade利刃出鞘】一起进入移动端webapp开发吧

前言 在移动浪潮袭来的时候&#xff0c;小钗有幸进入框架组做webapp框架开发&#xff0c;过程中遇到了移动端的各种坑&#xff0c;也产生了各种激情&#xff0c;就我们公司的发展历程来说 第一阶段&#xff1a;使用传统方式开发移动站点&#xff0c;少量引入HTML5元素 第二阶段…

题目理解。。

有时候一道大水题&#xff0c;因为英文描述可能有点复杂或者其它云云&#xff0c; 就比如那道PRO。。 别先被一道题吓一跳&#xff0c;&#xff0c;&#xff0c; 英文描述看深入一点总归会能解决的&#xff0c;尽可能多的考虑情况。大胆尝试。转载于:https://www.cnblogs.com/c…

C++多线程快速入门(四)shared_mutex以及读写锁应用

在前面的三讲中我们使用的mutex都是普通的std::mutex&#xff0c;这里介绍一下shared_mutex&#xff0c;版本为C17 std::shared_mutex的底层实现时操作系统提供的读写锁&#xff0c;在读多写少的情况下&#xff0c;该shared_mutex比mutex更加高效。 它提供了常用的四种方法&am…

Tornado/Python 学习笔记(一)

1.源代码下载及安装&#xff1a;http://www.tornadoweb.org/en/stable/ 2.python中xmlrpc库官方文档&#xff1a;https://docs.python.org/3/library/xmlrpc.html?highlightxmlrpc 3.xml介绍与学习&#xff1a;http://www.w3school.com.cn/xml/xml_intro.asp XML 被设计为传输…

spring-aop-annotation

1。假设你已经配好依赖注入那一块。此时的bean.xml为 <?xml version"1.0" encoding"UTF-8"?><beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:cont…

c++实现简单线程池代码

目录完整代码TaskPool.cppTaskPool.hmain.cpp完整代码 TaskPool.cpp // // Created by LENOVO on 2021/10/25. //#include "TaskPool.h" #include <functional>std::mutex printMutex;TaskPool::TaskPool() : m_bRunning(false) {}TaskPool::~TaskPool() {re…

Android静态图片人脸识别的完整demo(附完整源码)

Demo功能&#xff1a;利用android自带的人脸识别进行识别&#xff0c;标记出眼睛和人脸位置。点击按键后进行人脸识别&#xff0c;完毕后显示到imageview上。 第一部分&#xff1a;布局文件activity_main.xml [html] view plaincopyprint?<RelativeLayout xmlns:android&qu…

图论:最短路径搜索--Dijkstra算法(c代码实现)

最近因为辞职&#xff0c;有不少闲功夫&#xff0c;重温下数据结构&#xff0c;顺便练练手。今天说说最短路径搜索算法中的Dijkstra原理和实现。 一&#xff1a;简介 这个算法用于解决图中单源最短路径问题。所谓单源节点是指给定源节点&#xff0c;求图中其它节点到此源节点的…

C++多线程快速入门(五)简单线程池设计

目录设计思路主线程运行逻辑task以及taskpool设计详细流程讲解完整代码打印结果往期回顾设计思路 线程池实际上就是一组线程&#xff0c;当我们需要异步执行一些任务时&#xff0c;经常要通过OS频繁创建和销毁线程&#xff0c;不如直接创建一组在程序生命周期内不会退出的线程…