高效的Linux系统编程环境
因为笔者的电脑是Windows,所以要进行Linux系统编程不得不准备一台虚拟机,当然子系统Ubuntu也是可以的,因为昨天解决了一个虚拟机固定IP的问题, 《CentOS7虚拟机设置固定IP》 所以一旦连接稳定,那么就可以开始开发了,哈哈,今天主要是通过Clion这个工具(和IDEA是亲兄弟)来进行高效的Linux系统编程环境搭建!
一、准备Linux环境
只要有一台装了Linux的虚拟机就可以,我使用的是CentOS7 Server版,所以,平时使用起来也是直接拿Xshell一连接就可以使用了
二、在Linux下准备开发工具
Cmake 3.x 以上 + gdb 7.8.x 以上 + gcc + gcc-g++
首先卸载预装Cmake 2
1yum remove cmake
安装必要环境
1yum install -y gcc g++ gcc-c++ make automake texinfo wget
安装Cmake
1wget https://cmake.org/files/v3.14/cmake-3.14.0.tar.gz
2tar -xf cmake-3.14.0.tar.gz
3cd cmake-3.14.0
4./configure
5make
6make install
7
8# 安装好后的Cmake位于 /usr/local/share/cmake-3.13/,可执行程序位于/usr/local/bin/cmake
9# 为了让CLion能够自动识别,构建软连接
10ln -s /usr/local/bin/cmake /usr/bin/cmake
如果wget很慢,推荐使用我的
1wget https://img.zouchanglin.cn/cmake-3.14.0.tar.gz
安装gdb
1# 首先安装依赖,termcap
2wget https://ftp.gnu.org/gnu/termcap/termcap-1.3.1.tar.gz
3tar -xf termcap-1.3.1.tar.gz
4cd termcap-1.3.1
5./configure
6make
7make install
如果安装的依赖包下载很慢,推荐用我的
1wget https://img.zouchanglin.cn/termcap-1.3.1.tar.gz
如果依赖包安装完成,开始下一步
1# 卸载预装gdb
2yum remove -y gdb
3
4# 安装gbd
5wget http://mirrors.ustc.edu.cn/gnu/gdb/gdb-7.9.tar.xz
6tar -xf gdb-7.9.tar.xz
7cd gdb-7.9
8./configure
9make
10make install
11
12# gdb将被安装到/usr/local/share/gdb目录,可执行程序位于/usr/local/bin/gdb
13# 为了让CLion能够自动识别,构建软连接。
14ln -s /usr/local/bin/gdb /usr/bin/gdb
如果gdb下载很慢,推荐用我的
1wget https://img.zouchanglin.cn/gdb-7.9.tar.xz
三、CLion配置remote主机
四、愉快的写代码吧
自动同步代码,超人性化提示,唯一的缺点就是对于不懂CMakeList的同学就Over了,下面复习一下CMakeList
五、CMakeList构建项目
cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。 在Windows下也可以使用Cmake进行大型项目的构建,比如我之前编译过OpenCV的源码,就是通过VisualStudio的编译器配合Cmake来完成的!
1. 指定 cmake 的最小版本
1cmake_minimum_required(VERSION 3.4.1)
这行命令是可选的,我们可以不写这句话,但在有些情况下,如果 CMakeLists.txt 文件中使用了一些高版本 cmake 特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行 cmake。
2. 设置项目名称
1project(demo)
这个命令不是强制性的,但最好都加上。它会引入两个变量 demo_BINARY_DIR 和 demo_SOURCE_DIR,同时,cmake 自动定义了两个等价的变量 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR。
3. 设置编译类型
1add_executable(demo demo.cpp) # 生成可执行文件
2add_library(common STATIC util.cpp) # 生成静态库
3add_library(common SHARED util.cpp) # 生成动态库或共享库
add_library 默认生成是静态库,通过以上命令生成文件名字,
- 在 Linux 下是: demo libcommon.a libcommon.so
- 在 Windows 下是: demo.exe common.lib common.dll
4. 指定编译包含的源文件
4.1 明确指定包含哪些源文件
1add_library(demo demo.cpp test.cpp util.cpp)
4.2 搜索所有的 cpp 文件
aux_source_directory(dir VAR) 发现一个目录下所有的源代码文件并将列表存储在一个变量中。
自定义搜索规则
1file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
2add_library(demo ${SRC_LIST})
3# 或者
4file(GLOB SRC_LIST "*.cpp")
5file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
6add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
7# 或者
8aux_source_directory(. SRC_LIST)
9aux_source_directory(protocol SRC_PROTOCOL_LIST)
10add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
5. 查找指定的库文件
find_library(VAR name path)查找到指定的预编译库,并将它的路径存储在变量中。 默认的搜索路径为 cmake 包含的系统库,因此如果是 NDK 的公共库只需要指定库的 name 即可
1find_library( # Sets the name of the path variable.
2 log-lib
3
4 # Specifies the name of the NDK library that
5 # you want CMake to locate.
6 log )
6. 设置包含的目录
1include_directories(
2 ${CMAKE_CURRENT_SOURCE_DIR}
3 ${CMAKE_CURRENT_BINARY_DIR}
4 ${CMAKE_CURRENT_SOURCE_DIR}/include
5)
Linux 下还可以通过如下方式设置包含的目录
1set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")
7. 设置链接库搜索目录
Linux 下还可以通过如下方式设置包含的目录
1set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")
8. 设置 target 需要链接的库
1target_link_libraries( # 目标库
2 demo
3
4 # 目标库需要链接的库
5 # log-lib 是上面 find_library 指定的变量名
6 ${log-lib} )
在 Windows 下,系统会根据链接库目录,搜索xxx.lib 文件,Linux 下会搜索 xxx.so 或者 xxx.a 文件,如果都存在会优先链接动态库(so 后缀)
8.1 指定链接动态库或静态库
1target_link_libraries(demo libface.a) # 链接libface.a
2target_link_libraries(demo libface.so) # 链接libface.so
8.2 指定全路径
1target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a)
2target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.so)
8.3 指定链接多个库
1target_link_libraries(demo
2 ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a
3 boost_system.a
4 boost_thread
5 pthread)
9. 设置变量
9.1 set 直接设置变量的值
9.2 set 追加设置变量的值
9.3 list 追加或者删除变量的值
1set(SRC_LIST main.cpp)
2list(APPEND SRC_LIST test.cpp)
3list(REMOVE_ITEM SRC_LIST main.cpp)
4add_executable(demo ${SRC_LIST})
六、CMake项目示例
1、简单项目
新建文件 main.c,内容如下,新建文件 CMakeLists.txt(命名必须是 CMakeLists.txt,注意大小写)
一般我们采用 cmake 的 out-of-source 方式来构建(即生成的中间产物和源代码分离),这样做可以让生成的文件和源文件不会弄混,且目录结构看起来也会清晰明了。所以推荐使用这种方式,至于这个文件夹的命名并无限制,我们习惯命名为 build。
我们进入build文件夹,执行cmake..
, ..
表示上一级目录,cmake 会在上一级目录下找到 CMakeLists.txt 文件并编译,并生成如下图所示的一些中间文件
直接执行 make命令,生成可执行程序,如下图:
2、复杂项目
CMakeList.txt
1cmake_minimum_required (VERSION 2.8)
2project(demo)
3aux_source_directory(. DIR_SRCS)
4# 添加math子目录
5add_subdirectory(math)
6# 指定生成目标
7add_executable(demo ${DIR_SRCS})
8# 添加链接库
9target_link_libraries(demo MathFunctions)
main.c
1#include <stdio.h>
2#include "math/MathFunctions.h"
3
4int main() {
5 printf("Hello World!\n");
6 printf("Add(1,2) ret = %d\n", add(1,2));
7 return 0;
8}
math里的CMakeList.txt
math里的MathFunctions.h 和MathFunctions.c
1#ifndef define _MATHFUNCTIONS_H__
2#define _MATHFUNCTIONS_H__
3
4int add(int num, int num2);
5
6#endif //!define _MATHFUNCTIONS_H__
1#include <stdio.h>
2#include "MathFunctions.h"
3
4int add(int num, int num2){
5 return num + num2;
6}
同样的也只需要进入build目录,进行cmake ..