CMake第二课--安装文件

CMake第二课  安装文件

一.完整过程

  手把手教你学CMake,上一节讲的HelloWorld比较简单。这一节我们对它进行完善,让它看起来更像一个工程;并把它安装到自己的电脑上。

====================================================================================

#先建一个空文件夹“2”  它的路径是/home/guo/cmake_practice/2     标红的那部分改成自己的用户名

绝对路径:/home/guo/cmake_practice/2(工程目录)

----------------------------------------------------------

目标:

1.为工程添加一个子目录 src,用来放置工程源代码;

2.添加一个子目录 doc,用来放置这个工程的文档 hello.txt

3.在工程目录添加文本文件 COPYRIGHT, README;

4.在工程目录添加一个 runhello.sh 脚本,用来调用 hello二进制可执行程序

5.最终安装这些文件:

将 hello 二进制与 runhello.sh 安装至/home/guo/ cmake_practice/2/usr/bin;

将 doc 目录的内容安装到/home/guo/cmake_practice/2/usr/doc;

将COPYRIGHT/README 安装到/home/guo/cmake_practice/2/usr/share

----------------------------------------------------------

工程目录结构(按照下面结构添加文件夹和文件):

1.在主工程目录(/home/guo/cmake_practice/2)建一个CMakeLists.txt文件,

CMakeLists.txt文件内容为:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)  # 声明要求的 cmake 最低版本

PROJECT(hello)                       # 声明一个 cmake 工程

ADD_SUBDIRECTORY(src  bin)

INSTALL(FILES     COPYRIGHT README  DESTINATION   usr/share)
INSTALL(PROGRAMS  runhello.sh       DESTINATION   usr/bin)
INSTALL(DIRECTORY doc/              DESTINATION   usr/doc)

2.建一个空的COPYRIGHT.txt和README.txt文件

3.一个runhello.sh文件  内容为./hello(hello为生成的可执行二进制文件名)

4.一个doc文件夹          里面建一个空的hello.txt文件

5.一个usr空文件夹       存放安装结果,可建可不建,执行install命令后相关路径文件夹会自动创建

6.一个src文件夹(/home/guo/cmake_practice/2/src)里面main.cpp 和 CMakeLists.txt

src/main.cpp 文件内容:

#include <iostream>
using namespace std;  
int main( int argc, char** argv )
{
    cout<<"Hello World!"<<endl;
    return 0;
}

src/CmakeLists.txt 文件内容:

CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )  # 声明要求的 cmake 最低版本

#SET(EXECUTABLE_OUTPUT_PATH    ${PROJECT_BINARY_DIR}/bin)
#SET(LIBRARY_OUTPUT_PATH       ${PROJECT_BINARY_DIR}/lib)

ADD_EXECUTABLE( hello  main.cpp )

INSTALL( TARGETS  hello  RUNTIME  DESTINATION  usr/bin)

-------------------------------------------------------------------------------

外部编译

开终端

cd  /home/guo/cmake_practice/2

mkdir build    (新建build文件夹)

cd  build

cmake   -DCMAKE_INSTALL_PREFIX=/home/guo/cmake_practice/2 ..

(指定绝对路径 <prefix>;因外部编译,所以用‘ ..’)

make

sudo  make install

这样我们就把想要安装的文件安到了指定路径。

====================================================================================

 

二.详细解释

1.  ADD_SUBDIRECTORY(source_dir   [binary_dir]    [EXCLUDE_FROM_ALL])

  • 这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除。比如,工程的 example,可能就需要工程构建完成后,再进入 example 目录单独进行构建。
  • 上面的例子定义了将 src 子目录加入工程,并指定编译输出(包含编译中间结果)路径为bin 目录。如果不进行 bin 目录的指定,那么编译结果(包括中间结果)都将存放在build/src 目录(这个目录跟原有的 src 目录对应);指定 bin 目录后,相当于在编译时将 src 重命名为 bin,所有的中间结果和目标二进制都将存放在 bin 目录。

 2.  ADD_SUBDIRECTORY 指令不论是否指定编译输出目录,我们都可以通过 SET 指令重新定义 EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH 变量来指定最终的目标二进制的位置(指最终生成的 hello 或者最终的共享库,不包含编译生成的中间文件)。

  • SET(EXECUTABLE_OUTPUT_PATH    ${PROJECT_BINARY_DIR}/bin)    #可执行二进制的输出路径为 build/bin
  • SET(LIBRARY_OUTPUT_PATH            ${PROJECT_BINARY_DIR}/lib)     #库的输出路径为 build/lib
  • <projectname>_BINARY_DIR 和 PROJECT_BINARY_DIR 变量,他们指的编译发生的当前目录;如果是内部编译,就相当于 PROJECT_SOURCE_DIR 也就是工程代码所在目录;如果是外部编译,指的是外部编译所在目录,也就是本例中的 build目录。

注意:应该把这两条指令写在工程的 CMakeLists.txt 还是 src 目录下的CMakeLists.txt 

把握一个简单的原则,在哪里 ADD_EXECUTABLE 或 ADD_LIBRARY,如果需要改变目标存放路径,就在哪里加入上述的定义!在这个例子里,当然就是指 src 下的 CMakeLists.txt 了。

 3.  安装 COPYRIGHT/README

直接修改主工程文件 CMakelists.txt,加入以下指令:

INSTALL(FILES COPYRIGHT README   DESTINATION   usr/share)

 4.  安装 runhello.sh

直接修改主工程文件 CMakeLists.txt,加入如下指令:

INSTALL(PROGRAMS   runhello.sh   DESTINATION   usr/bin)

 5.  安装 doc 中的 hello.txt

这里采用的方式是安装 doc目录中的内容,也就是使用 ” doc/”.在工程文件中添加:

INSTALL(DIRECTORY   doc/  DESTINATION   usr/doc)

 6.  安装二进制可执行文件

在scr文件夹下的 CMakeLists.txt中(在哪里 ADD_EXECUTABLE 或 ADD_LIBRARY,就在哪添加添加)

INSTALL( TARGETS  hello  RUNTIME  DESTINATION  usr/bin)

 7.  如果没有定义 CMAKE_INSTALL_PREFIX 会安装到什么地方?

你可以尝试以下,cmake ..  ; make ; make install,你会发现CMAKE_INSTALL_PREFIX 的默认定义是/usr/local(根目录下的)。

-------------------------------------------------------------------------------

 

三.如何安装?(大体分为四个步骤)

  • 第一步:在对应的CMakeLists.txt文件中,添加INSTALL 指令,用于定义安装规则。安装的内容可以包括目标二进制、动态库、静态库以及文件、目录、脚本等。
  • 第二步:终端输入,指定绝对路径 cmake    -DCMAKE_INSTALL_PREFIX=/home/guo /cmake_practice/2 ..(外部编译)
  • 第三步:make
  • 第四步:sudo make install

1.  目标文件的安装

INSTALL(TARGETS targets...

[[ARCHIVE|LIBRARY|RUNTIME]

            [DESTINATION <dir>]

            [PERMISSIONS permissions...]

            [CONFIGURATIONS

[Debug|Release|...]]

            [COMPONENT <component>]

            [OPTIONAL]

            ] [...])

  • 参数中的 TARGETS 后面跟的就是我们通过 ADD_EXECUTABLE 或者 ADD_LIBRARY 定义的目标文件,可能是可执行二进制、动态库、静态库;
  • 目标类型也就相对应的有三种,ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME特指可执行目标二进制;
  • DESTINATION 定义了安装的路径,如果路径以“ / ”开头,那么指的是绝对路径,这时候CMAKE_INSTALL_PREFIX 其实就无效了。如果你希望使用CMAKE_INSTALL_PREFIX 来定义安装路径,就要写成相对路径,即不要以“ / ”开头,那么安装后的路径就是${CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径>

举个简单的例子:(注意 在哪ADD_EXECUTABLE的 或者 ADD_LIBRARY 的 ,就写在那个文件里的CMakeLists.txt)

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 目录

       注意:我们自己定义的库名XXXX,生成的库会自动脑补成libXXXX

  • 绝对路径:是从根目录开始的路径;形如/home/guo/lib。
  • 相对路径:是从当前路径开始的路径;假如当前路径为/home/guo  要描述上述路径,只需输入lib。

 2.  普通文件的安装

INSTALL(FILES  files...  DESTINATION  <dir>

          [PERMISSIONS permissions...]

          [CONFIGURATIONS [Debug|Release|...]]

          [COMPONENT <component>]

          [RENAME <name>] [OPTIONAL])

可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路径下的相对路径。如果默认不定义权限 PERMISSIONS,安装后的权限为:

OWNER_WRITE, OWNER_READ,GROUP_READ,和 WORLD_READ,即 644 权限。

 3.  非目标文件的可执行程序安装(比如脚本之类)

INSTALL(PROGRAMS  files...  DESTINATION  <dir>

           [PERMISSIONS permissions...]

           [CONFIGURATIONS [Debug|Release|...]]

           [COMPONENT <component>]

           [RENAME <name>] [OPTIONAL])

跟上面的 FILES 指令使用方法一样,唯一的不同是安装后权限为:OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 权限。

 4.  目录的安装

INSTALL(DIRECTORY dirs... DESTINATION <dir>

           [FILE_PERMISSIONS permissions...]

           [DIRECTORY_PERMISSIONS permissions...]

           [USE_SOURCE_PERMISSIONS]

           [CONFIGURATIONS [Debug|Release|...]]

           [COMPONENT <component>]

           [[PATTERN <pattern> | REGEX <regex>]

           [EXCLUDE] [PERMISSIONS permissions...]] [...])

这里主要介绍其中的 DIRECTORY、PATTERN 以及 PERMISSIONS 参数。

  • DIRECTORY 后面连接的是所在 Source 目录的相对路径,但务必注意: abc 和 abc/有很大的区别。如果目录名不以" / "结尾,那么这个目录将被安装为目标 路径下的 abc;如果目录名以" / "结尾,代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。
  • PATTERN             用于使用正则表达式进行过滤。
  • PERMISSIONS    用于指定 PATTERN 过滤后的文件权限。

例子:

INSTALL(DIRECTORY  icons  scripts/  DESTINATION  share/myproj

           PATTERN "CVS" EXCLUDE

            PATTERN "scripts/*"

            PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ

            GROUP_EXECUTE GROUP_READ)

这条指令的执行结果是:

  • 将 icons 目录安装到 <prefix>/share/myproj ;
  • 将 scripts/中的内容安装到<prefix>/share/myproj不包含目录名为 CVS 的目录;对于 scripts/* 文件指定权限为 OWNER_EXECUTE, OWNER_WRITE ,OWNER_READ ,GROUP_EXECUTE, GROUP_READ。

 

 

posted @ 2018-09-05 21:01  小果子啊  阅读(1148)  评论(0编辑  收藏  举报