关于编译工具 make 及远程开发 C/C++ 项目的思路 (CLion)

即使作为一个 Javaer,如果想要在 *nix 平台下使用一些新版本的框架或软件,也得不可避免地需要自己从官方下载源代码,然后编译成可执行程序。比如编译 Hadoop,Redis,亦或者是 JDK 的源代码 ( JVM :从手动编译 JDK 开始 - 掘金 (juejin.cn))。即使我们不专门从事 C/C++ 开发,应该也会对下面的命令比较熟悉了:

./configue
cmake ..
make && make install
复制代码

除此之外,官网通常会要求编译的环境包括但不限于这些工具,比如:g++gccmakecmake 等等。本篇简单地对这些工具做一些基本介绍,包括如何跨环境 DEBUG 或者是编写 C/C++ 代码,以 CLion IDE 为例。

编译源码所需的工具

如果只是使用官方提供的框架,那么一般根据官方的指示安装相关版本的工具即可。如果是 C/C++ 开发者,选择哪些工具取决于团队需求。

gcc / g++

简单来说,gcc ( GNU C Complier ) 负责处理 C 程序,而 g++ ( GNU C++ Complier ) 负责处理 C++ 程序。但事实上,两者都能够编译 *.c*.cpp 文件,其主要的区别是:

  1. gcc 会区分处理 *.c*.cpp 文件;
  2. g++ 将两者都视作 *.cpp 进行处理。

严谨地说,gcc/g++ 自身并不是编译器,它们倒更像是一个 driver:用于驱动 cc1cc1plus 等编译器。使用 g++ 编译文件时,g++ 会自动链接标准库 STL,而 gcc 不会自动链接 STL

make

make 工具解决了一个大型 C/C++ 项目的编译问题。首先,它需要一个 Makefile 文件来指示它应该如何工作:比如工程中的哪些源文件需要编译以及如何编译、需要创建那些中间文件以及如何创建这些中间文件、如何最后产生我们想要得可执行文件,等等。不过,由于编写 Makefile 本身也是一件痛苦的事情,因此有必要在 make 的基础上再引入两个工具:./configureCmake。它们都能够起到简化编写 Makefile 的作用。

我们经常会使用这两个组合的命令:make && make install。其中,make 负责编译项目,而 make install 则负责安装。

./configure

./configure 本质上是一种叫 autoconf 的构建工具自动生成的构建文件,它以 shell script 的形式存储,在 Cmake 之前是 C/C++ 的主流构建工具,基于 configure 规则文件代替开发者生成 Makefile

Cmake

Cmake 的全称是 Cross Plaform Make。故名思义,它是一个跨平台编译工具,可以用简单的语句描述所有平台的安装 / 编译过程。

比如说,Windows 下的 C/C++ 开发者一般会直接使用 Visual Studio 自带的工具生成项目,而 Linux 环境下的开发者则有可能使用 QT Creater 工具生成项目,但是两个不同平台上面的项目不能相互移植,这就有了 CMake 的用武之地。开发者可以先编写一个 CMakeLists.txt 文件,将需要的 .h.cpp 文件包含进来,然后在不同的平台使用 CMake 工具调用各自的编译器生成各自的兼容于平台的工程 ( 这和 Java 的跨平台思路基本一致 )。

Cmake 在 Linux/Unix 平台生成 makefile,在 Mac 平台生成 xcode,在 Windows 平台,可以生成 MSVC 的工程文件。

另外,跨平台编译同一个项目时,环境不匹配是运行失败的一大原因。如果 OS 中默认的 g++/gcc 不是官方指定的 ( 或者是团队所约束的 ) 版本,或者是 OS 内保留了多个版本的 gcc/g++ ,那么有两种方式解决:

第一种方法,进入 CMakeLists.txt 文件内部进行修改:

SET(CMAKE_C_COMPILER "/home/public/local/bin/gcc")
SET(CMAKE_CXX_COMPILER "/home/public/local/bin/g++")
复制代码

第二种方法,在调用 cmake 工具之前主动声明环境变量 ( 这是临时的,退出命令行之后就会失效 ):

export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/to/your/project
make
复制代码

make 缺少依赖库的解决办法

在少部分情况下,make 源码的过程中可能会因为缺少依赖库而出错:

canning dependencies of target bitmap_test
[ 91%] Building CXX object unitest/CMakeFiles/bitmap_test.dir/bitmap_test.cpp.o
[ 92%] Linking CXX executable ../bin/bitmap_test
/home/lijunhu/Documents/miniob_X/build/bin/bitmap_test: error while loading shared libraries: libevent-2.2.so.1: cannot open shared object file: No such file or directory
复制代码

比如,笔者曾经在使用 make 工具编译 googleTest 框架的过程中遇到上述的错误,显示的原因是缺少依赖的 libevent-2.2.so.1 库。这有两种可能性:

  1. 缺少这个库。
  2. 这个库不在系统的搜索路径内。

可以通过 find 命令查看这个库在环境内是否存在:

find / -name xxx.so
复制代码

如果库文件确实存在,那么唯一的可能性就是它不在系统的库文件 (.so) 搜索路径上了。第一种方法是将库文件挪动到 /usr/lib 下:

sudo cp xxx.so /usr/lib/
复制代码

另一种不错的解决方案是使用 ldconfig 添加系统的搜索路径。

步骤 1. 编辑链接配置文件。编辑 vim /etc/ld.so.conf,确认内容是否为如下,不是则修改为如下:

include /etc/ld.so.conf.d/*.conf
复制代码

步骤 2. 进入 /etc/ld.so.conf.d 目录内,创建 *.conf 文件。文件名随意,扩展名必须为 .conf

cd /etc/ld.so.conf/
vim mylib.conf 
复制代码

步骤 4. 在文件内部,添加 .so 的路径,保存并退出。

步骤 5. 执行命令时期生效。

sudo ldconfig
复制代码

程序在运行时寻找 .so 库就会到添加的目录中寻找。

用 CLion 在远程部署 / 调试 C/C++ 代码

这种远程 DEBUG 的方法可以推广到 IntelliJ IDEA,Goland 等 JET BRAINS 公司旗下的其它编译器。

出于二次开发,或者是调试的目的,我们有时候可能会需要跨平台对 C/C++ 进行编译。比如,笔者的本地环境是 Windows,但工作环境却是 Linux。因此,想要在 Windows 上安装 make,就得先去安装一个 MinGW 工具,再选择下载依赖的包。

如果已经在云服务器 / 虚拟环境中有了现成的 C/C++ 环境,那么本机只要负责写源代码,然后在 Run / Debug 的场合再将这些源代码上传到已有环境去编译就好了 —— 下面以 CLion 工具为例介绍如何实现,这大概分为三个步骤:

  1. 在本地进行编码。
  2. 在编译之前,将本地的代码发送到远端。
  3. 用远端的 Cmake,make 等工具进行编译,DEBUG。

这种远程工作的思路可以推广到连接云服务器的情形,后面简称为远端。

使用远端环境编译并 DEBUG

本机只负责编写代码,那么就不需要额外的 Cmake,make 工具这些工具了。在 ToolChains 选项中新建一个 Remote Host,然后与远端建立一个 SFTP 连接。

clion_remote_toolchains.png

首先需要配置好 gcc,g++ 环境来保证 CMake 工具的运行。注意,笔者这里主动配置了 C Compiler 和 C++ Compiler 的路径,因此这里手动更改 gcc/g++ 的 path。默认情况下,在连接成功之后,IDE 便可以自动探测 CMake,make,gcc,g++ 的路径。配置完毕后,选择 OK。

在设置的 Cmake 项中,将刚才配置的 Toolchains 选上,选择 OK。

clion_remote_debug.png

之后,程序后续的 Run / DEBUG 将在远端进行。之后只需要在本地进行编程,随后将代码发送到远程,然后 DEBUG 即可。在每次 DEBUG 的时候,代码会自动部署到远程的 /tmp/... 某个临时文件夹下保存运行。

仅将项目源代码提交到远端

如果仅仅是想将代码上传到远端,打开 CLion 上方视窗的 Tools -> Development 即可设置:

clion_remote_update.png

点开 Configuration,进入配置界面,新建连接,连接方式选择 SFTP。

clion_remote_conn.png

Connection 填写完毕之后,不要关闭窗口,进入 Mappings,配置本地代码上传到远端的路径。

clion_remote_mappings.png

这些内容全配置完毕之后,选择 OK,保存配置。现在,在项目根目录中右键 Development ( 或者在 Tools -> Development ) 当中,可以看到有 Upload 选项了:

clion_remote_upload.png

可以自行设置 CLion 是否要实时上传代码更新。

参考资料

CLion 远程开发和调试C/C++代码 - IUNI_JM - 博客园 (cnblogs.com)

CLion 实现远程调试_Leo的博客-CSDN博客_clion 远程调试

CMakeLIsts.txt与Makefile的区别_jay463261929的博客-CSDN博客

c++编程基础(二)——Makefile与cmake入门_potxxx的博客-CSDN博客_cmake makefile

gcc和g++是什么关系? - 知乎 (zhihu.com)

configure、 make、 make install 背后的原理(翻译) - 知乎 (zhihu.com)

浅谈 make 工具 - 银河 - 博客园 (cnblogs.com)

CLion 远程开发和调试C/C++代码 - IUNI_JM - 博客园 (cnblogs.com)

CLion 实现远程调试_Leo的博客-CSDN博客_clion 远程调试

Guess you like

Origin juejin.im/post/7032329297960370207