视觉slam第一讲——cmake学习

平台:ubuntu16.04LTS。 语言:C\C++

辅助资料:
鸟哥linux私房菜链接:
https://pan.baidu.com/s/11DiNN58kwdQAECSOd3vqOA
提取码:knod
CMake Practice:链接:https://pan.baidu.com/s/1JX7OH0RIF3291uzKISdBkw
提取码:e8py
linux需要的知识很简单,一些基本操作就可,包括一些基本文件操作(ls、cp、mv,mkdir之类的)和vim的相关操作,需要补充linux知识的请看完鸟哥的6、7、10章节

vim学习可参考:https://blog.csdn.net/jjj96321/article/details/71305156
可以不安装这么些东西,达到代码高亮,显示行,tab键=4等等
配置好的.vimrc:http://pan.baidu.com/s/1i5oRFHb
直接放到Home下会自动隐藏。重启下就可以使用vim了。

ps:如果仅对当前用户使用的话放到Home下就可了,如果对整个系统所有用户有用的话放到/etc/vim/中(看不懂这里路径名怎么进去的去补linux6,7节知识)
在这里插入图片描述
如果Linux没问题可进入今天的学习了(提前下载上面的CMake Practice)。

cmake是一个构建代码,管理代码的工具。对于一个或者几个C\C++文件我们还可以一个个g++或gcc的去编译、链接。但是等到文件很多系统庞大的时候我们需要新的方式管理代码。
用cmake和IDE的关系:IDE里也调用了cmake的部分指令,只是可能不再终端里写,而是通过IDE可视化了,IDE也需要编写的CMakeLists.txt,两者都是为了高效管理代码而存在的,没有说谁好或者谁不好,但是两者都需要掌握的。

学习大纲:
1、安装
2、hello world
3、静态库与动态库生成

1、安装。
这里我推荐用apt-get下载,命令如下:sudo apt-get install cmake 可自动安装
或者官网(https://cmake.org/download/)下载tar文件,安装
2、hello world
在home目录下建立练习文件cmake_test,在cmake_test里建立第一节练习文件ch1
PS:可在linux下ctrl+shift+v、ctrl+shift+c,粘贴复制

cd ~
mkdir cmake_test
cd cmake_test
mkdir ch1

创建main.cpp并输入代码

#include <iostream.h>
int main(int argc,char** argv)
{
 printf("hello world form ti Main\n");
 return 0;
}

再写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句的所用分别是:
(1)新建名为HELLO的工程文件,
(2)SET指令用来定义变量,相当于SRC_LIST=main.c
多个文件可用SET(SRC_LIST main.c t1.c t2.c)相当于SRC_LIST是存放各种文件的地址
(3)MASSAGE指令用于信息输出
MESSAGE 指令的语法是:
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] “message to display”…)
这个指令用于向终端输出用户定义的信息,包含了三种类型:
SEND_ERROR,产生错误,生成过程被跳过。
SATUS,输出前缀为—的信息。
FATAL_ERROR,立即终止所有 cmake 过程.
这里使用的是 STATUS 信息输出,演示了由 PROJECT 指令定义的两个隐式变量
HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR

在后面的输出结果里这里显示的是二进制和源文件目录地址
-- This is BINARY dir /backup/cmake/t1
-- This is SOURCE dir /backup/cmake/t1

(4)ADD_EXECUTABLE(hello $ {SRC_LIST})
定义了这个工程会生成一个文件名为 hello 的可执行文件,相关的源文件是 SRC_LIST 中
定义的源文件列表, 本例中你也可以直接写成 ADD_EXECUTABLE(hello main.c)。
(5)补充:
变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
参数使用括弧括起,参数之间使用空格或分号分开。
指令是大小写无关的,参数和变量是大小写相关的。推荐你全部使用大写指令

使用外部构建的方式,在ch1下新建文件夹build,进入build后执行

cmake ..

区分cmake .是编译当前目录,cmake …是编译上级目录。
输出大概是这样的
– Check for working C compiler: /usr/bin/gcc
– Check for working C compiler: /usr/bin/gcc – works
– Check size of void*
– Check size of void* - done
– Check for working CXX compiler: /usr/bin/c++
– Check for working CXX compiler: /usr/bin/c++ – works
– This is BINARY dir /backup/cmake/t1
– This is SOURCE dir /backup/cmake/t1
– Configuring done
– Generating done
– Build files have been written to: /home/linker/test/t1
再build目录下构建一下

make

查看build目录下生成以下几个文件,绿色的为可执行文件,
在这里插入图片描述
输入./HELLO执行,结果如图
在这里插入图片描述
跟经典的 autotools 系列工具一样,运行:

make clean

即可对构建结果进行清理。

3、库文件生成
按照图所示文件结构生成
在这里插入图片描述
文件框架:
build 用于生成编译相关文件,日常编译使用
debug 用于生成cmake在debug模式下的编译相关文件
release 用于生成cmake在release模式下的编译相关文件
src 存放useHello.cpp(就是main)源文件
lib 存放库文件的.cpp
include 存放库文件的.h
doc 存放说明文件
这样main和库文件分开,就需要再src、lib和顶层各写一个CMakeLists.txt。
日常先贴各部分代码再说明用途和构建方式

src文件里

#include <iostream>
#include "hello.h"

int main()
{
	sayHello();
	return 0;
}

CMakeLists.txt(前面提到过,命令大小写都可,变量大小写有区分)

INCLUDE_DIRECTORIES(../include)
MESSAGE(${PROJECT_SOURCE_DIR})
SET(APP_SRC useHello.cpp)
ADD_EXECUTABLE(hello ${APP_SRC})
TARGET_LINK_LIBRARIES(hello lib hello_shared)
set_target_properties(hello PROPERTIES OUTPUT_NAME "sayhello")

INCLUDE_DIRECTORIES引入头文件搜索路径,hello.h位于跟src同级的目录include中的src文件里,…/include是上级目录下的include文件。如果安装好了库的话可以通过下面命令引入

INCLUDE_DIRECTORIES(/usr/include/hello)

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)
这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径
中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的
后面,你可以通过两种方式来进行控制搜索路径添加的方式:
1,CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过 SET 这个 cmake 变量为 on,可以将添加的头文件搜索路径放在已有路径的前面。
不添加make时会有
在这里插入图片描述
SET_TARGET_PROPERTIES,其基本语法是:
SET_TARGET_PROPERTIES(target1 target2 … PROPERTIES prop1 value1 …)
这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和 API 版本。
本例用来设置可执行文件的名字.target1的标准是,编译的时候会记录每个文件的名字,比如可执行文件通过ADD_EXECUTABLE定义为hello,库文件在lib下的CMakeLists里定义为libhello_shared和libhello_static;那么这里改名字会搜索target是谁,进而改谁。

TARGET_LINK_LIBRARIES为target添加共享库
不链接make时会
在这里插入图片描述

lib文件下

#include "hello.h"
#include <iostream>
void sayHello() {std::cout<<"Hello SLAM"<<std::endl;}

CMakeLists.txt

INCLUDE_DIRECTORIES(../include)
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(libhello_shared SHARED ${LIBHELLO_SRC})
ADD_LIBRARY(libhello_static STATIC ${LIBHELLO_SRC})
INSTALL(TARGETS libhello_shared libhello_static
	LIBRARY DESTINATION lib
	ARCHIVE DESTINATION lib
	)
INSTALL(FILES ../include/hello.h DESTINATION include/hello)

增添库命令
ADD_LIBRARY(libname [SHARED|STATIC|MODULE]
[EXCLUDE_FROM_ALL] source1 source2 … sourceN)

SHARED,动态库
STATIC,静态库
MODULE,在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。
EXCLUDE_FROM_ALL 参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手工构建。
用这两句构建动态库和静态库

ADD_LIBRARY(libhello_shared SHARED ${LIBHELLO_SRC})
ADD_LIBRARY(libhello_static STATIC ${LIBHELLO_SRC})

编译成功后会多两个文件,分别是动态库libhello_shared.so 静态库libhello_static.a

先引入一个常用变量
CMAKE_INSTALL_PREFIX。
CMAKE_INSTALL_PREFIX 变量类似于 configure 脚本的 –prefix,常见的使用方法看
起来是这个样子:
cmake -DCMAKE_INSTALL_PREFIX=/usr .

INSTALL 指令包含了各种安装类型,我们需要一个个分开解释:
目标文件的安装:
INSTALL(TARGETS targets…
[[ARCHIVE|LIBRARY|RUNTIME]
[DESTINATION

]
[PERMISSIONS permissions…]
[CONFIGURATIONS
[Debug|Release|…]]
[COMPONENT ]
[OPTIONAL] […])
参数中的 TARGETS 后面跟的就是我们通过 ADD_EXECUTABLE 或者 ADD_LIBRARY 定义的目标文件,可能是可执行二进制、动态库、静态库。
目标类型也就相对应的有三种,ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME
特指可执行目标二进制。
DESTINATION 定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候
CMAKE_INSTALL_PREFIX 其实就无效了。如果你希望使用 CMAKE_INSTALL_PREFIX 来
定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是
{CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径>
举个简单的例子:
INSTALL(TARGETS myrun mylib mystaticlib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION libstatic
)
上面的例子会将:
可执行二进制 myrun 安装到{CMAKE_INSTALL_PREFIX}/bin 目录
动态库 libmylib 安装到{CMAKE_INSTALL_PREFIX}/lib 目录
静态库 libmystaticlib 安装到{CMAKE_INSTALL_PREFIX}/libstatic 目录
特别注意的是你不需要关心 TARGETS 具体生成的路径,只需要写上 TARGETS 名称就可以
了。

include下

#ifndef __HELLO_H
#define __HELLO_H
#inlcude <iostream.h>
void sayHello(); 
#endif

顶层CmakeLists.txt

cmake_minimum_required(VERSION 3.5)
PROJECT(HELLO)
add_subdirectory(src)
add_subdirectory(lib)

顶层要讲的是两个命令
cmake_minimum_required()这个命令是指cmake执行的最低版本,如果版本低于这里设置的版本号则会出错,在对build文件夹进行cmake …的时候报错如下:
在这里插入图片描述

还有一个指令是add_subdirectory
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存
放的位置。
EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除,比如,工程
的 example,可能就需要工程构建完成后,再进入 example 目录单独进行构建(当然,你
也可以通过定义依赖来解决此类问题)
比如上面我们hello.c放到lib里,main.c当道了src里,就需要通过这条指令添加源文件的子目录。

学完这些cmake算是入门了,后面的内容需要在实践中不断学习深入。不会去百度和看书。

好了,下班了下班了。
在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值