前段时间,参与了公司一个项目,需要开发linux服务程序,因为之前没接触过,对shell、GDB、makefile不熟悉,项目要的又紧,所以决定使用更为熟悉的vs编译器来远程调试linux程序,等有时间了再把makefile和GDB调试等熟悉起来,下面把个人经验讲一下,希望能帮到后面有这方面需要的人。
因为之前在学习过程中浏览过其他很多有用的博文,所以有些环节的内容直接用其他博文代替,本文着重讲解vs属性和gcc编译项之间的关联关系,因为我发现这部分内容其实很少有详细讲解到的。
首先把我的环境介绍一下:
1. Microsoft Visual Studio Community 2019 (社区版的,毕竟免费么,当然也是有些BUG的,此处不多说,安装选项里把linux相关的控制台、共享库等套件装上),vs2015、2017、2019都有远程调试linux的功能。
2. Ubuntu18 (Ubuntu 7.4.0-1ubuntu1~18.04.1);
3. VMware® Workstation 14 Player(也是个免费版本,不过建议安装workstation,功能更完善);
其中Ubuntu系统上必须要装的有 有以下几项:
2. gcc、g++、gdb 用于编译调试你的c、c++代码,安装命令:
3. 网络IP,建议写成静态IP,防止重启linux系统后IP会变,那样vs的远程连接器也需要重新删除再连接,很麻烦,至于怎样修改ubuntu的IP本文不再赘述,网上方法很全,只要能保证主机和虚拟机之间相互能ping通。
至此,linux环境都已经装完了,下面在vs上增加远程连接器,方法在官网有详细步骤,https://docs.microsoft.com/zh-cn/cpp/linux/connect-to-your-remote-linux-computer?view=vs-2019
具体步骤本文不再赘述,只提一点建议:
1. 建议用root用户登录,因为工程里如果需要链接.so共享库,而这些共享库放在了/opt 或者 /usr等系统目录的话是需要管理员权限才能访问的,而这时如果你用普通用户登录了则会出现代码的链接错误(亲身经历的坑),ubuntu系统默认是不允许以root用户登录的,需要略作修改(修改方法:https://blog.csdn.net/f_IT_boy/article/details/89072168)
远程连接建立好以后vs会把linux上的sdk开发环境拷贝一份到vs的缓存目录用于咱们在win系统上开发,这时我们就可以愉快的进行编码工作了,先建立一个Linux控制台程序,具体步骤参照: https://blog.csdn.net/ZYZMZM_/article/details/89044885
这时,我们看下一解决方案资源管理器,除了main.cpp,还有一个外部依赖项,里面有很多乱七八糟的代码文件,其实这就是vs从linux系统拷贝来的sdk开发环境,如果双击其中一项,然后转到其目录,会发现这不就是linux上的环境目录么..
这时到linux系统里打开相应的目录也能找到相应的文件
这样,就能大体明白vs到底是怎么工作的了。
我们平时实际的工作中,肯定不会是简单的写几句代码就完事的,会有各种的第三方的动态库啊静态库啊头文件啊等等的,熟悉linux编程的都知道,我如果调用第三方库只需要在makefile的编译规则里用 -l来链接即可,如果要包含头文件目录只需要 -I(大写i)来包含即可, 那换到vs上该咋配置呢,下面就针对第三方库、头文件以及一些基本配置进行详细讲解。
1. 先看看vs属性页的基本配置有啥:
属性-常规:
这里定义了一些基本的环境信息,从字面上其实就能理解,主要关注的有:远程生成根目录(~/projects 也就是$RemoteRootDir)、远程生成项目目录、输出目录(最终的可执行程序目录默认是bin)、中间目录(.o文件的目录默认是obj)、目标文件名等(其实都需要理解一下)
属性-调试
这里面只需要关注程序参数即可,程序参数也就是命令行参数,如果需要就填上,主要用于调试过程,用空格分隔;
属性-复制源
这个选项是决定vs把哪些文件复制到linux系统上的工程目录里,只要加到解决方案资源管理器里的文件都会默认复制过去,如果有其他没在资源管理器中的文件可以加到第三项中,vs也会复制过去,更详细的解释见官方链接:https://docs.microsoft.com/zh-cn/cpp/linux/configure-a-linux-project?view=vs-2019
以上就是vs的基础配置了。
再来看看怎样包含头文件路径、库路径以及链接依赖库
这时候我们先编译一下程序,看看当前的编译规则是什么,vs build一下...
从输出内容里翻一翻会找到vs帮咱们组织生成的编译规则。那这时候如果我需要调用一个叫 util.so的共享库怎么办呢?首先来新建一个叫util.so的共享库,里面有个获取两个int值之和的函数 int get_sum(const int& a, const int& b);,新建空项目
属性里将配置类型修改为动态库
添加一个cpp文件一个头文件,并把get_sum方法实现,注意需要打开选项位置无关代码也就是 -fPIC,这样可以使用相对路径再编译阶段链接动态库
这时候编译整个解决方案就把两个工程都编译完成并生成相应的linuxTest.out和libutil.so了
现在我们在linuxTest工程里使用get_sum接口
先把util.h部署到ubuntu系统的/opt/test/public/include目录中,再把libutil.so部署到/opt/test/public/lib里
然后在linuxTest工程属性里把包含路径和库路径设置一下,然后再把libutil.so链接一下,注意,这里设置的都是Linux系统里相应的绝对路径,一定是绝对路径。
注意,这里链接的名称不需要带lib前缀和.so后缀,编译器会自动加的。
配置完毕后,先编一下工程,成功!
至此,程序调用动态库已经编译通过,下面来部署一下运行环境,程序运行时加载的库默认会从LD_LIBRARY_PATH全局变量指定的目录里寻找,如果想要指定自己的目录则需要在/etc/profile里增加
export LD_LIBRARY_PATH=/opt/test/public/lib:$LD_LIBRARY_PATH
保存之后要 source命令使修改生效 source /etc/profile
这样之后就能在自定义的库目录找到libUtil.so库了.
运行一下,可以正常调用动态库接口,完毕!
以上就是vs2019调试linux程序的详细步骤了,最重要的还是配置环境和单步调试。