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