Linux下C/C++开发环境4大件,2024.09.01

一、前言

Win下C/C++开发,单就环境来说,熟悉VS环境就差不多了,也许最好熟悉MFC、DotNet等微软特定的库及平台。

Linux下C/C++开发,就环境来说,要熟悉这4大件

  • Linux常用命令。(只列一下git吧,其它略过。)
  • gcc、g++、make套件命令使用。
  • 能处理Makefile内容。
  • 能使用gdb调试。

我做了5年以上Linux下的C、C++(gcc)开发,也做了5年以上Windows下的C++ MFC(VS)开发。我也做过3年以上Python开发(Python 3.6以上,Linux、Windows都做)及Python-C++混编项目。

以前最熟悉的是Linux gcc环境。最近几年,反而Win VS用的多。甚至最近这些东西都没怎么碰了一段时间几个月了吧。

Linux下g++、gcc、make等应用,有时简单称为gcc环境开发。

二、Linux常用命令

这块内容本文就基本就略过了。其实也不仅仅常见命令,如果真做过项目,对于Linux发行版的安装,硬盘分区,编译内核,裁剪内核,调试驱动小模块,及裁剪文件系统,网络远程登陆,搭建服务器应用,整bootloader,无所不涉及过。

所以,尽量收拢一下。

sed、grep、find、ssh、scp、tar,apt-get或yum、rpm、readelf、ldd这些常用吧。cp、ls这些则真不提了。

vi、vim,那真必须会,而且是信仰。我在Win VS中都要装个vim插件。

以上都不展开了。

另外,shell脚本常用的命令,比如:

#!/bin/bash

MEM_TOTAL=$(free -m | awk '/Mem:/ {print $2}')

除了sed,awk常用吧。cut常用吧。

这样吧,列一下常见git代码仓库使用算了。

三、git命令的基本使用

Git 管理代码仓库时,文件流转的三个工作区域:Git 的工作区,暂存区域,以及本地仓库。

还要加一个远程仓库。

假定git已经安装了,而且假设要连远程仓库。

git config --global user.name 你的用户名
git config --global user.email 你的邮箱地址

这是你在一台Linux上要做的第一件事。

ssh-keygen -t ed25519 -C “comments-X”

这是第二件事,.ssh/id_ed25519.pub公钥拿去贴进远程仓库界面。

这样后面使用git命令时和远程交互就免密了。

接着在仓库的本地工作目录,执行git init。

从远程仓库拉代码到本地,用git clone。

git add ./

如果新加文件,那就执行git add。

或者修改哪个代码文件后。

用git status查看,本地修改或加了哪些文件。

git commit -m "代码提交信息"

用git commit,提交到本地仓库。

用git diff,你可以设置调用vimdiff查看有什么代码修改冲突需要解决的。冲突解决了就commit。

仅提交到本地不行,还需要推送到远程仓库。

git push origin master

因此这条就是推送到远程仓库master分支了。

前面提交前,最好执行git pull获得远程仓库最新的代码版本。

常用的还有git checkout和git revert命令。

当然也少不了git log命令查看操作记录。

Linux下git这些命令最常用了。

不过如图,我在Win下时,用的是小乌龟git的GUI。从SVN年代就开始用小乌龟了。

四、Makefile的基本使用

一两个代码文件,使用gcc命令就够了,但如果项目文件一多,或者嫌弃命令不好记,或者老是敲一长串命令麻烦,那就用Makefile。

有了Makefile,执行make时,自动会去调用里面指定的命令。

all:
	g++ -O2 -o app main.cpp foo.cpp

clean:
	rm -f app

这是一个最简单的Makefile例子。

g++前面缩进空格,不能真是空格,一定要是TAB按键出来的缩进,这是很脑残的。现今应该还是这样吧。

这个例子,使用了两个.cpp源代码文件,而且是编译链接一步到位产生二进制可执行的app程序。

all: main.o foo.o
    g++ -o app main.o foo.o

main.o:
	g++ -o main.o -c main.cpp

也可以如此拆开成两步,第一步是g++ -o main.o -c main.cpp先编译,然后再all下面的链接build。

项目稍大后,会有库API,静态库、动态库。

libtest1.a : test1.o
    ar -cr libtest1.a test1.o 

test1.o : test1.cpp
    g++ -c -o test1.o test1.cpp

这是Makefile里调用ar做一个静态库的例子。

export LD_LIBRARY_PATH:=$LD_LIBRARY_PATH:/func

test : test.cpp func/libfunc.so
    g++ -o test test.cpp -L./func -lfunc

func/libfunc.so : func/func.cpp func/func.h
    g++ -fPIC -shared -o func/libfunc.so func/func.cpp

而这g++ -fPIC -shared -o func/libfunc.so func/func.cpp是动态库例子。

今天略过cmake。

五、Makefile和gcc命令的进一步使用

进一步使用,就要用到大量的宏变量了,而且是和Linux shell命令结合。

FILES := $(wildcard $(SRCDIR)/*.cpp)

OBJS := $(foreach file, $(FILES), $(file:.cpp=.o))

这样的Makefile,就把某目录下的所有.cpp文件当作源文件,不需要手动往里面一个一个的加。

CC = gcc
CXX = g++
CFLAGS = -Wall -O2
CXXFLAGS = -Wall -O2 -I$(LIBMTN_CFG_PATH)/include
LDFLAGS = -lssl -lcrypto -lcrypt

CC、CXX宏变量,可以是gcc、g++,也可以是gcc-arm之类的跨平台使用,并且真跨平台时,gcc或gcc-arm也可以去自动获得。

如果需要gdb去调试,CXXFLAGS可以加上-g。-I是指定外部库的头文件包含路径。

具体来说,LDFLAGS的-lssl 表示链接 OpenSSL 的 SSL 库,-lcrypto 表示链接 OpenSSL 的 Crypto 库。

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

有了宏变量,写编译的那两行就可以变成这样。

关于Makefile宏变量内容其实挺多,这里粗糙一点,简单提一两句就算了。

今天略过m4宏处理器。

六、使用gdb调试程序

gcc build程序时开启了调试信息保留,后续就可以使用gdb调试了。

调试的内容就是去查看程序的状态,包括断点、变量值、函数调用栈、及哪个线程的信息等。

第1个常用命令就是list/l,列出源代码的第几行开始的片段。或者列出哪个函数。

设置断点是第2个常用命令,break(b) 行号或函数名。

(gdb) b 25

在gdb中,敲b 25就是在当前代码的第25行设置断点。

断点也可以设置在某个函数。

info(i) break(或breakpoints) :查看各断点信息。i break。

disable breakpoints n:禁用序号为n的断点。dis break n。

enable breakpoints n:启用序号为n的断点。e break n。

delete(d) breakpoints n:删除序号为n的断点。del break n。不指定n则删除所有断点。

r或run:当没有断点时运行程序,当有断点时运行到断点处。

n 或 next:单步调试,当使用n命令进行单步调试时,gdb会执行下一行代码,如果下一行是执行某个函数,不会进入函数,而是就此执行函数了。

s或step:单步调试,当使用s命令进行单步调试时,gdb同样会执行下一行代码。但是,如果下一行代码是一个函数调用,s命令会进入这个函数内部,并从函数的第一条语句开始逐行执行。

finish:执行到当前函数返回,然后停下来等待后续命令。

print ( p ):打印一个表达式的值,表达式可以由变量构成。

    sum = a + b;

(gdb) p sum

p 变量:打印某个变量的值。比如,sum = a + b行运行后,用p查看sum的结果。

print(p) /x 地址,显示为16进制值。

set var:修改某个变量的值。

continue(或c):继续执行被调试的程序,直到遇到下一个断点、程序结束或遇到其他导致程序停止的事件。

display 变量名:跟踪查看一个变量,每次停下来都显示它的值。

undisplay n:取消对序号为n的变量的跟踪。

until :主要作用是继续执行程序,直到当前栈帧(通常是当前函数)的返回点,或者遇到下一个断点。

until n:n为某一行代码的行号,该命令会使程序运行至第n行代码处停止。

breaktrace(或bt):查看各级函数调用及参数。就是查看函数调用栈,即stack frames。

frame n(f n)n为对应的堆栈。

info (i) locals:查看当前栈帧局部变量的值。

info all-registers:查看所有寄存器情况。

quit (q):退出gdb。

info threads 命令可以查询被调试程序中的线程的信息。

thread  n 命令可以切换当前线程,如thread 2把线程2切换为当前线程。

指定某个线程或所有线程执行:

  • thread apply all bt:打印所有线程的调用栈信息
  • thread apply 3 bt:打印线程3的调用栈信息
  • thread apply 2-3 bt:打印线程2和线程3的调用栈信息

针对特定线程设置断点

break 5 thread 3 # 在第5行设置断点,仅对线程3生效
break 5 thread 3 if <condition> # 在第5行设置条件断点,仅对线程3生效

还有一个命令是,指定源文件,因为有时不知怎的,会发生gdb就没找到源文件的情况。

directory(dir) path添加一个源文件路径到当前路径前,可以多个源文件路径。

GNU gdb (GDB) 7.1-ubuntu
(gdb) list main
1192    ls.c: No such file or directory.
in ls.c
(gdb) directory ~/src/coreutils-7.4/src/
Source directories searched: /home/hchen/src/coreutils-7.4:$cdir:$cwd
(gdb) list main
1192        }
1193    }
1194
1195    int
1196    main (int argc, char **argv)
1197    {

今天文章就先这样吧。等有时间再完善内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值