C++ 常用命令行开发工具(Linux)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 常用命令行开发工具(Linux)相关的知识,希望对你有一定的参考价值。
1、简介
编译的四个阶段:预处理(扩展各个宏与文件)、编译(得到汇编代码)、汇编(得到机器码)、链接(得到可执行文件)
预处理:编译处理宏定义等宏命令(eg:#define)——生成后缀为“.i”的文件
编译:将预处理后的文件转换成汇编语言——生成后缀为“.s”的文件
汇编:由汇编生成的文件翻译为二进制目标文件——生成后缀为“.o”的文件
连接:多个目标文件(二进制)结合库函数等综合成的能直接独立执行的执行文件——生成后缀为“.out”的文件
2、gcc / g++
实际使用中我们更习惯使用 gcc 指令编译 C 语言程序,用 g++ 指令编译 C++ 代码。需要强调的一点是,这并不是 gcc 和 g++ 的区别,gcc 指令也可以用来编译 C++ 程序,同样 g++ 指令也可以用于编译 C 语言程序。
GCC 编译器已经为我们提供了调用它的接口,对于 C 语言或者 C++ 程序,可以通过执行 gcc 或者 g++ 指令来调用 GCC 编译器。
当然,gcc 指令也为用户提供了“手动指定代表编译方式”的接口,即使用 -x 选项。例如,gcc -xc xxx 表示以编译 C 语言代码的方式编译 xxx 文件;而 gcc -xc++ xxx 则表示以编译 C++ 代码的方式编译 xxx 文件。
但如果使用 g++ 指令,则无论目标文件的后缀名是什么,该指令都一律按照编译 C++ 代码的方式编译该文件。也就是说,对于 .c 文件来说,gcc 指令以 C 语言代码对待,而 g++ 指令会以 C++ 代码对待。但对于 .cpp 文件来说,gcc 和 g++ 都会以 C++ 代码的方式编译。
gcc -v
g++ -v
# gcc 编译c代码
gcc demo.c
gcc main.c func.c -o app.out
# gcc 编译c++代码
gcc -xc++ -lstdc++ -shared-libgcc demo.cpp
gcc -xc++ -lstdc++ -shared-libgcc demo.cpp -o democpp.exe
# g++ 编译c++代码
g++ demo.cpp
g++ demo.cpp -o democpp.exe
<font color=blue>首先说明:gcc 和 GCC 是两个不同的东西
GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。
gcc是GCC中的GUN C Compiler(C 编译器)
g++是GCC中的GUN C++ Compiler(C++编译器)
gcc 命令的常用选项:
选项 | 解释 |
---|---|
-ansi | 只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色, 例如 asm 或 typeof 关键词。 |
-c | 只编译并生成目标文件。 |
-DMACRO | 以字符串"1"定义 MACRO 宏。 |
-DMACRO=DEFN | 以字符串"DEFN"定义 MACRO 宏。 |
-E | 只运行 C 预编译器。 |
-g | 生成调试信息。GNU 调试器可利用该信息。 |
-IDIRECTORY | 指定额外的头文件搜索路径DIRECTORY。 |
-LDIRECTORY | 指定额外的函数库搜索路径DIRECTORY。 |
-lLIBRARY | 连接时搜索指定的函数库LIBRARY。 |
-m486 | 针对 486 进行代码优化。 |
-o FILE | 生成指定的输出文件。用在生成可执行文件时。 |
-O0 | 不进行优化处理。 |
-O 或 -O1 | 优化生成代码。 |
-O2 | 进一步优化。 |
-O3 | 比 -O2 更进一步优化,包括 inline 函数。 |
-shared | 生成共享目标文件。通常用在建立共享库时。 |
-static | 禁止使用共享连接。 |
-UMACRO | 取消对 MACRO 宏的定义。 |
-w | 不生成任何警告信息。 |
-Wall | 生成所有警告信息。 |
2.1 system(执行shell 命令)
头文件:
#include<stdlib.h>
定义函数:
int system(const char * string);
函数说明:
system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。
test_sys.c:
#include<stdlib.h>
#include<stdio.h>
int
main(int argc, char *argv[])
system("ls -al /etc/docker /etc/nginx /etc/firefox");
return 0;
gcc test_sys.c -o test.exe
./test.exe
2.2 popen(建立管道I/O)
头文件
#include<stdio.h>
定义函数
FILE * popen( const char * command,const char * type);
函数说明
popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c 来执行参数command的指令。参数type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。
test_popen.c:
#include<stdio.h>
main()
FILE* fp;
char buffer[80];
fp=popen("cat /etc/nginx", "r");
fgets(buffer,sizeof(buffer),fp);
printf("%s", buffer);
pclose(fp);
gcc test_popen.c -o test.out
./test.out
2.3 vfork+exec(新建子进程)
使用vfork()新建子进程,然后调用exec函数族。 test_vfork.c:
#include<unistd.h>
#include<stdio.h>
main()
char * argv[]="ls", "-al", "/etc/firefox", (char*)0 ;
if(vfork() == 0)
execv("/bin/ls", argv);
else
printf("it is the parent process\\n");
gcc test_vfork.c -o test.out
./test.out
3、clang
Clang是一个C语言、C++、Objective-C语言的轻量级编译器。源代码发布于BSD协议下。Clang将支持其普通lambda表达式、返回类型的简化处理以及更好的处理constexpr关键字。
Clang是一个C++编写、基于LLVM、发布于LLVM BSD许可证下的C/C++/Objective-C/Objective-C++编译器。它与GNU C语言规范几乎完全兼容(当然,也有部分不兼容的内容,包括编译命令选项也会有点差异),并在此基础上增加了额外的语法特性,比如C函数重载(通过__attribute__((overloadable))来修饰函数),其目标(之一)就是超越GCC。 win10 的 msvc,Ubuntu 的 gcc 和 clang gcc 是c的编译器,g++是c++的编译器。
3.1 下载和安装clang
# yum install epel-release
yum install clang
检查是否安装成功(查看clang版本,有显示即为成功):
clang --version
clang -v
3.2 clang和gcc比较
3.2.1 gcc
GCC(GNU Compiler Collection,GNU编译器套装),是一套由GNU开发的编程语言编译器。它是一套以GPL及LGPL许可证所发布的自由软件,也是GNU项目的关键部分,亦是自由的类Unix及苹果电脑Mac OS X 操作系统的标准编译器。GCC(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。
GCC原名为GNU C语言编译器(GNU C Compiler),因为它原本只能处理C语言。GCC很快地扩展,变得可处理C++。之后也变得可处理Fortran、Pascal、Objective-C、Java、Ada,以及Go与其他语言。
原本用C开发,后来因为LLVM、Clang的崛起,令GCC更快将开发语言转换为C++。许多C的爱好者在对C++一知半解的情况下主观认定C++的性能一定会输给C,但是Taylor给出了不同的意见,并表明C++不但性能不输给C,而且能设计出更好,更容易维护的程序。
3.2.2 clang
Clang(发音为/ˈklæŋ/类似英文单字clang) 是一个C、C++、Objective-C和Objective-C++编程语言的编译器前端。它采用了底层虚拟机(LLVM)作为其后端。它的目标是提供一个GNU编译器套装(GCC)的替代品。作者是克里斯·拉特纳,在苹果公司的赞助支持下进行开发,而源代码授权是使用类BSD的伊利诺伊大学厄巴纳-香槟分校开源码许可。
Clang项目包括Clang前端和Clang静态分析器等。
3.2.3 LLVM
“ LLVM , 它是一个 编译器 的基础建设,以 C++ 写成。它是为了任意一种编程语言写成的程序,利用 虚拟技术 ,创造出 编译时期 , 链结时期 , 运行时期 以及“闲置时期”的优化。
因为GCC的编译器已经慢慢无法满足苹果的需求,因此,苹果开发了Clang与LLVM来完全取代GCC,Xcode4之后,苹果的默认编译器已经是LLVM了。Clang作为编译器前端,LLVM作为编译器后端。
4、make
Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。
make --version
make -v
–f :指定作为makefile的文件的名称。 如果不用该选项,那么make程序首先在当前目录查找名为makefile的文件,如果没有找到,它就会转而查找名为Makefile的文件。如果您在Linux下使用GNU Make的话,它会首先查找GNUmakefile,之后再搜索makefile和Makefile。按照惯例,许多Linux程序员使用Makefile,因为这样能使Makefile出现在目录中所有以小写字母命名的文件的前面。
4.1 例子1
- Makefile文件内容如下:
all:
gcc -Wall test.c -o test.out
执行命令如下:
make
# or
make all
- Makefile文件内容如下:
all:
gcc -c -Wall test.c
gcc -Wall test.o -o test.out
执行命令如下:
make
- Makefile文件内容如下:
all:
gcc -c -Wall test.c
gcc -c -Wall anotherTest.c
gcc -Wall test.o anotherTest.o -o test.out
执行命令如下:
make
4.2 例子2
- Makefile文件内容如下:
all: test
test: test.o anotherTest.o
gcc -Wall test.o anotherTest.o -o test.out
test.o: test.c
gcc -c -Wall test.c
anotherTest.o: anotherTest.c
gcc -c -Wall anotherTest.c
clean:
rm -rf *.o test.out
执行命令如下:
make all
make test
make clean
通过 -B 选项让所有目标总是重新建立:
make -B
使用 -d 选项打印调试信息:
make -d | more
使用 -C 选项改变目录: 你可以为 make 命令提供不同的目录路径,在寻找 Makefile 之前会切换目录的。 但是你想运行的 make 命令的 Makefile 文件保存在 ../make-dir/ 目录下,你可以这样做:
make -C ../make-dir/
通过 -f 选项将其它文件看作 Makefile:
make -f my_makefile
4.3 问题汇总
可能出现的问题如下: <font color=red>“Makefile:1: *** 遗漏分隔符 。 停止。”?
5、cmake
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。
5.1 下载cmake
ubuntu系统下只需要如下一句命令即可:
# ubuntu
sudo apt install cmake
CMake 提供了多种版本,包括但不限于 “RC 版本”(Release Candidate)和“稳定版本”(Latest Release)。切换到系统存放源代码的目录,再用 curl 命令通过该链接将 CMake 的二进制分发压缩包下载下来:
cd /usr/local/src
curl -LO https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz
# or
yum install -y wget
wget -c https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz
# wget -c https://cmake.org/files/v3.26/cmake-3.26.0-rc1-linux-x86_64.tar.gz
5.2 安装cmake
CMake 二进制分发压缩包下载完毕后,运行以下两条命令将压缩包解压缩,并将得到的文件夹移动到系统的本地程序目录,同时将文件夹重命名为 cmake(即 /usr/local/cmake):
tar -xvf cmake-3.26.0-rc1-linux-x86_64.tar.gz
# tar zxvf cmake-3.22.2-linux-x86_64.tar.gz
mv cmake-3.26.0-rc1-linux-x86_64 /usr/local/cmake
查看安装后的路径:
ls /usr/local/cmake
如果你是第一次按照本文步骤安装 CMake,为方便之后运行 CMake 的相关命令,请运行以下两条命令将 CMake 的可执行文件目录添加到系统环境变量 PATH 中:
echo export PATH="/usr/local/cmake/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
查看~/.bashrc:
vi ~/.bashrc
#在最后添加export PATH=/usr/local/cmake/bin:$PATH
查看cmake的版本:
cmake --verison
6、gdb
GDB是一个强大的命令行调试工具。虽然X Window提供了GDB的图形版DDD,但是我仍然更钟爱在命令行模式下使用GDB。
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。 一般来说,GDB主要帮忙你完成下面四个方面的功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、动态的改变你程序的执行环境。
gdb
一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如:
gcc -g hello.c -o hello
g++ -g hello.cpp -o hello
如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。
# 在进入函数func时,设置一个断点。可以敲入break func,或是直接就是b func
gdb
b main
7、git
Git --- The stupid content tracker, 傻瓜内容跟踪器。Linus Torvalds 是这样给我们介绍 Git 的。 Git 是用于 Linux内核开发的版本控制工具。与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持(wingeddevil注:这得分是用什么样的服务端,使用http协议或者git协议等不太一样。
并且在push和pull的时候和服务器端还是有交互的。),使源代码的发布和交流极其方便。 Git 的速度很快,这对于诸如 Linux kernel 这样的大项目来说自然很重要。 Git 最为出色的是它的合并跟踪(merge tracing)能力。
7.1 下载和安装git
Git是目前流行的非常好用的版本控制工具,这里介绍两种安装方式,1、yum安装,2、从github上下载最新的源码编译后安装。
在Linux上是有yum安装Git,非常简单,只需要一行命令:
yum -y install git
输入 git --version查看Git是否安装完成以及查看其版本号:
git --version
当然我们也可以从GitHub上下载最新的源码编译后安装。
# 需要删除旧的Git
yum -y remove git
# 下载,https://github.com/git/git/releases
wget https://github.com/git/git/archive/refs/tags/v2.39.1.tar.gz
# 进入/usr/local 目录解压git文件
tar -zxvf v2.39.1.tar.gz
# 安装编译所需要的依赖。
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker
# 编译git源码,进入cd /usr/local/git-2.39.1 目录
make prefix=/usr/local/git all
# 安装git至/usr/bin/git路径
make prefix=/usr/local/git install
# 配置环境变量
vi /etc/profile
# 在底部加上如下
export PATH=$PATH:/usr/bin/git/bin
# 刷新环境变量
source /etc/profile
# 查看Git是否安装完成
git --version
7.2 使用git
命令 | 功能 |
---|---|
git init | 在本地的当前目录里初始化git仓库 |
git status | 查看当前仓库的状态 |
git add -A | 增加目录中所有的文件到缓存区 |
git add file | 增加相应文件到缓存区 |
git commit -m "信息" | 将缓存区中更改提交到本地仓库 |
git log | 查看当前版本之前的提交记录 |
git reflog | 查看HEAD的变更记录,包括回退 |
git branch -b branch_name | 建立一个新的分支 |
git diff | 查看当前文件与缓存区文件的差异 |
git checkout -- file | 取消更改,将缓存区的文件提取覆盖当前文件 |
git reset --hard 版本号 | 回退到相应版本号,同样也可以回退到未来的版本号 |
git clean -xf | 删除当前目录中所有未追踪的文件 |
git config --global core.quotepath false | 处理中文文件名 |
常用命令如下:
git remote add origin git@github.com:<用户名>/<仓库名>.git
git pull origin master //因为github建立仓库时会有readme.md文件,先要拷贝一份
git push -u origin master //将本地仓库链接到master分支上,你当然可以链接到其他分支
git push //上传你的本地仓库
8、bash
Bash Shell脚本是用Bash编写的计算机程序,它是一个包含了自定义数量命令的纯文本文件,用于在Linux系统上自动循环执行重复性任务。
8.1 Centos bash: 运行 ./xxx.sh: 权限不够
编写脚本xxx.sh:
#! /bin/bash
echo hello world;
chmod 777 ./xxx.sh
# chmod u+x test.sh
./xxx.sh
或者
chmod +x ./xxx.sh
或者
# 该方式不需要在第一行指定解释器信息
/bin/sh xxx.sh
# or
sh xxx.sh
sh /root/test.sh
8.2 Linux中解决cannot access ‘\\r’: No such file or directory
碰到这种情况,是因为脚本文件在windows环境下编辑过后再上传到linux服务器导致换行符格式不对。使用dos2unix命令行即可解决。 Ubuntu系统打开Windows下生成的文本文件,会在每行的末尾出现’^M’ 原因就是Windows和Linux的回车符是不同的。
在Windows下回车符是\\r\\n回车换行
在Linux下回车符是\\n
最简单、最常用的解决方法是使用dos2unix命令转换:
## ubuntu
apt-get install dos2unix
# or
apt-get install tofrodos
## centos
#进入root用户后,使用
yum install dos2unix。
dos2unix命令 用来将DOS格式的文本文件转换成UNIX格式的(DOS/MAC to UNIX text file format converter)。DOS下的文本文件是以\\r\\n作为断行标志的,表示成十六进制就是0D 0A。而Unix下的文本文件是以\\n作为断行标志的,表示成十六进制就是0A。DOS格式的文本文件在Linux底下,用较低版本的vi打开时行尾会显示^M,而且很多命令都无法很好的处理这种格式的文件,如果是个shell脚本,。而Unix格式的文本文件在Windows下用Notepad打开时会拼在一起显示。因此产生了两种格式文件相互转换的需求,对应的将UNIX格式文本文件转成成DOS格式的是unix2dos命令。
dos2unix [-hkqV] [-c convmode] [-o file ...] [-n infile outfile ...]
-k:保持输出文件的日期不变
-q:安静模式,不提示任何警告信息。
-V:查看版本
-c:转换模式,模式有:ASCII, 7bit, ISO, Mac, 默认是:ASCII。
-o:写入到源文件
-n:写入到新文件
# 最简单的用法就是dos2unix直接跟上文件名
dos2unix file
# 如果一次转换多个文件
dos2unix file1 file2 file3
dos2unix -o file1 file2 file3
# 如果想把转换的结果保存在别的文件
dos2unix -n oldfile newfile
# 如果要保持文件时间戳不变
dos2unix -k file
dos2unix -k file1 file2 file3
dos2unix -k -o file1 file2 file3
dos2unix -k -n oldfile newfile
# 转换当前目录下所有文件
find -type f | xargs dos2unix
也可以使用*通配符来同时修改多个,或者使用空格隔开文件名的方式。
8.3 readelf查看可执行文件信息
readelf命令,一般用于查看ELF格式的文件信息,常见的文件如在Linux上的可执行文件,动态库(.so)或者静态库(.a) 等包含ELF格式的文件。以下命令的使用是基于android编译出来的so文件上面去运行。
- 选项 -h(elf header),显示elf文件开始的文件头信息。
readelf -h ./test007.out
- 选项 -l(program headers),segments 显示程序头(段头)信息(如果有数据的话)。
readelf -l ./test007.out
- 选项 -S(section headers),sections 显示节头信息(如果有数据的话)。
readelf -S ./test007.out
- 选项 -s,symbols 显示符号表段中的项
readelf -s ./test007.out
- 选项 -r,relocs 显示可重定位段的信息。
readelf -r ./test007.out
- 选项 -d,dynamic 显示动态段的信息。
readelf -d ./test007.out
- 选项 -A,arch-specific 显示CPU构架信息。
readelf -A ./test007.out
- 选项 -a,all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I。
readelf -a ./test007.out
- 选项 -H,help 显示readelf所支持的命令行选项。
readelf -H ./test007.out
- 选项 -V,version-info 显示版本段的信息。
readelf -V ./test007.out
8.4 常见Shell的种类
Linux Shell的种类很多,用户可以通过查看/etc/shells文件中的内容来查看自己主机中当前有哪些种类的Shell。
cat /etc/shells
<font color=green>Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言。
<font color=blue>shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。
<font color=pink>shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中的其他应用程序所调用。用户在提示符下输入的命令都由shell先解释然后传给Linux核心。
<font color=purple>Linux中的shell有多种类型,常见的有Bourne Again Shell (简称bash)、Bourne Shell(简称sh)、C-Shelll(简称csh)、Korn Shell(简称ksh)。
<font color=grey>sh是Unix最初使用的shell,并且在每种Unix上都可以使用。sh在shell编程方面相当优秀,但在处理与用户的交互方面做得不如csh和ksh。Linux默认的shell是bourne again shell(bash),它与sh完全向后兼容。bash放在bin/bash中。sh和bash都是Linux上的默认shell,而bash是sh的升级版。
结语
如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;
╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地
//(ㄒoㄒ)//,就在评论处留言,作者继续改进;
o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;
(✿◡‿◡)
感谢各位大佬童鞋们的支持!
( ´ ▽´ )ノ ( ´ ▽´)っ!!!
以上是关于C++ 常用命令行开发工具(Linux)的主要内容,如果未能解决你的问题,请参考以下文章
在Linux操作系统的纯命令行界面,如rpm -ivh或者scp这些命令使用时会出现进度条和百分比,如何用shell实现