Linux 基础入门操作-实验二 cmake使用介绍下
5 cmake 介绍
5.1 介绍
cmake 是 kitware 公司以及一些开源开发者在开发几个工具套件(VTK)的过程中衍生品,最终形成体系,成为一个独立的开放源代码项目。项目的诞生时间是 2001 年。其官方网站是 www.cmake.org,可以通过访问官方网站获得更多关于 cmake 的信息。cmake的流行其实要归功于 KDE4 的开发(似乎跟当年的 svn 一样,KDE 将代码仓库从 CVS 迁移到SVN,同时证明了 SVN 管理大型项目的可用性),在 KDE 开发者使用了近 10 年 autotools之后,他们终于决定为 KDE4 选择一个新的工程构建工具,其根本原因用 KDE 开发者的话来“ ”说就是:只有少数几个 编译专家 能够掌握 KDE 现在的构建体系(admin/Makefile.common),在经历了 unsermake, scons 以及 cmake 的选型和尝试之后,KDE4 决定使用 cmake 作为自己的构建系统。在迁移过程中,进展异常的顺利,并获得了 cmake 开发者的支持。所以,目前的 KDE4 开发版本已经完全使用 cmake 来进行构建。像 kdesvn,rosegarden 等项目也开始使用 cmake,这也注定了 cmake 必然会成为一个主流的构建体系。
5.2 版本下载
cmake 目前已经成为各大 Linux 发行版提供的组件,比如 Everest 直接在系统中包含Fedora 在 extra 仓库中提供,所以,需要自己动手安装的可能性很小。如果你使用的操作系统(比如 Windows 或者某些 Linux 版本)没有提供 cmake 或者包含的版本较旧,建议你直接从 cmake 官方网站下载安装。http://www.cmake.org/HTML/Download.html在这个页面,提供了源代码的下载以及针对各种不同操作系统的二进制下载,可以选择适合自己操作系统的版本下载安装。因为各个系统的安装方式和包管理格式有所不同,在此就不再赘述了,相信一定能够顺利安装 cmake。
5.3 代码演示
CmakeLists.txt 文件内容,文件名不要写错了。
PROJECT (HELLO)
SET(SRC_LIST main.c)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello SRC_LIST)
5.4 语法规则
1,变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
2,指令(参数 1 参数 2…) 参数使用括弧括起,参数之间使用空格或分号分开。以上面的 ADD_EXECUTABLE 指令为例,如果存在另外一个 func.c 源文件,就要写成:
ADD_EXECUTABLE(hello main.c func.c)或者
ADD_EXECUTABLE(hello main.c;func.c)
3,指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令。
4. 上面的 MESSAGE 指令我们已经用到了这条规
MESSAGE(STATUS “This is BINARY dir” ${HELLO_BINARY_DIR})
也可以写成:
MESSAGE(STATUS “This is BINARY dir ${HELLO_BINARY_DIR}”)
5. PROJECT 指令的语法是 函数名
6. SET 指令的语法是:SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
7. ADD_EXECUTABLE(hello ${SRC_LIST})
5.5 进一步建立工程-采用外部链接方式
新建一个空的文件build,一个src文件包含了main.c CMakeLists.txt , 一个CMakeLists.txt.
主要的cmakeLists.txt
cmake_minimum_required(VERSION 3.10)
PROJECT (HELLO VERSION 1.0)
#SET(SRC_LIST main.c)
ADD_SUBDIRECTORY(src bin)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR})
#ADD_EXECUTABLE(hello ${SRC_LIST})
src里面的cmakeListt.txt
cmake_minimum_required(VERSION 3.10)
ADD_EXECUTABLE(hello main.c)
修改输出路径:
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
5.6 安装文件
创建makefile文件,运行make命令
DESTDIR=/tmp/test
install:mkdir -p $(DESTDIR)/usr/bininstall -m 755 hello $(DESTDIR)/usr/bin
添加临时环境变量,方便运行程序
export PATH=/tmp/test/usr/bin:$PATH
5.7 共享库-动态库
`
在 t3 目录下建立 CMakeLists.txt,内容如下:
PROJECT(HELLOLIB)
ADD_SUBDIRECTORY(lib)
在 lib 目录下建立两个源文件 hello.c 与 hello.h
hello.c 内容如下:
#include “hello.h”
void HelloFunc()
{
printf(“Hello World\n”);
}
hello.h 内容如下:
#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
void HelloFunc();
#endif
在 lib 目录下建立 CMakeLists.txt,内容如下:
SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
5.8 共享库-静态库
ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})
5.9 常见变量
1,
CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
<projectname>_BINARY_DIR
这三个变量指代的内容是一致的,如果是 in source 编译,指得就是工程顶层目录,如果
是 out-of-source 编译,指的是工程编译发生的目录。PROJECT_BINARY_DIR 跟其他
指令稍有区别,现在,你可以理解为他们是一致的。
2,
CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
<projectname>_SOURCE_DIR
这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录。
也就是在 in source 编译时,他跟 CMAKE_BINARY_DIR 等变量一致。
PROJECT_SOURCE_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的。
3,
CMAKE_CURRENT_SOURCE_DIR
指的是当前处理的 CMakeLists.txt 所在的路径,比如上面我们提到的 src 子目录。
4,
CMAKE_CURRRENT_BINARY_DIR
如果是 in-source 编译,它跟 CMAKE_CURRENT_SOURCE_DIR 一致,如果是 out-of-source 编译,他指的是 target 编译目录。
使用我们上面提到的 ADD_SUBDIRECTORY(src bin)可以更改这个变量的值。使用 SET(EXECUTABLE_OUTPUT_PATH <新路径>)并不会对这个变量造成影响,它仅仅修改了最终目标文件存放的路径。
5,
CMAKE_CURRENT_LIST_FILE
输出调用这个变量的 CMakeLists.txt 的完整路径
6,
CMAKE_CURRENT_LIST_LINE
输出这个变量所在的行
7,
CMAKE_MODULE_PATH
这个变量用来定义自己的 cmake 模块所在的路径。如果你的工程比较复杂,有可能会自己编写一些 cmake 模块,这些 cmake 模块是随你的工程发布的,为了让 cmake 在处理CMakeLists.txt 时找到这些模块,你需要通过 SET 指令,将自己的 cmake 模块路径设置一下。
比如
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
这时候你就可以通过 INCLUDE 指令来调用自己的模块了。
8,
EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH
分别用来重新定义最终结果的存放目录,前面我们已经提到了这两个变量。
9,
PROJECT_NAME
返回通过 PROJECT 指令定义的项目名称。
6 自动运行
6.1 编译代码,把代码放到合适位置
/tmp/test/usr/bin/led_blink
6.2 创建 systemd 服务文件
在 /etc/systemd/system/ 目录下创建一个服务文件,例如 hello.service:
[Unit]
Description=hello Program
After=network.target[Service]
ExecStart=/tmp/test/usr/bin/hello
Restart=always[Install]
WantedBy=multi-user.target
6.3 启用并启动服务
启用服务并设置为开机自启动
sudo systemctl enable hello.service
sudo systemctl start hello.service
6.4 检查服务状态
确认服务是否正常运行:
sudo systemctl status hello.service
6.5 关闭西服务
sudo systemctl stop hello.service
sudo systemctl disable hello.service
6.6 删除服务
sudo rm /etc/systemd/system/hello.service