Basic 05-installing
# 介绍
这个例子展示了
- 如何生成一个
make install目标,用该目标来安装文件和二进制文件。 - 如何运行一个使用了动态链接库的可执行目标文件,并且被链接的共享库文件夹不在可执行目标的文件夹内。
(本例子基于上一个共享库的例子进行构建,只是在上一个例子的基础上,把它的文件安装到了其他地方)
本例的目录🌲:
.
├── cmake-examples.conf # 用于测试安装的配置文件,内部只有几行注释
├── CMakeLists.txt # 包含了所有的CMake命令
├── include
│ └── installing
│ └── Hello.h
├── README.adoc
└── src
├── Hello.cpp
└── main.cpp
2
3
4
5
6
7
8
9
10
# 概念解释
CMake 提供了添加 make install 目标的能力,我们可以通过该目标安装二进制文件,库和其他文件到某一特定的路径。默认的安装路径由变量 CMAKE_INSTALL_PREFIX 指定。该变量的值可以使用 cmake .. -DCMAKE_INSTALL_PREFIX=/install/location 进行修改。
被安装的所有文件和目录都是由函数 install() 指定的。比如:
- 它将名为
cmake_examples_inst_bin的构建目标对应的二进制文件的二进制文件安装到${CMAKE_INSTALL_PREFIX}/bin目录中
install (TARGETS cmake_examples_inst_bin
DESTINATION bin)
2
其中 TARGET 表明 cmake_examples_inst_bin 是一个 target,而且确实,我们知道这是一个可执行目标。
- 它将名为
cmake_examples_inst的构建目标对应的库文件安装到指定的目录${CMAKE_INSTALL_PREFIX}/lib中
install (TARGETS cmake_examples_inst
LIBRARY DESTINATION lib)
2
其中 TARGET 表明 cmake_examples_inst 是一个 target,我们知道这是一个库目标。
- 它将项目源代码目录 (
${PROJECT_SOURCE_DIR}/include/) 中的include目录下的所有头文件安装到include目录${CMAKE_INSTALL_PREFIX}/include下
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION include)
2
同上, DIRECTORY 表明 ${PROJECT_SOURCE_DIR}/include/ 是一个文件目录。
- 它安装一个配置文件到
${CMAKE_INSTALL_PREFIX}/etc目录下
install (FILES cmake-examples.conf
DESTINATION etc)
2
同上, FILES 表明 ${CMAKE_INSTALL_PREFIX}/etc 是一个文件。
总结来说, install() 可以用来安装下面的几种文件到指定的目录:
- 目标文件 (即编译汇编后的二进制文件) 和库文件 (即共享库或者静态库) - 使用
TARGET指定 - 目录 - 使用
DIRECTORY指定 - 其他文件 (比如配置文件) - 使用
FILES指定
其他还有一些可以安装的对象见 offical manual (opens new window)
提示
运行 make install 命令安装完成后,CMake 生成一个包含了所有安装文件详细信息,安装位置的 install_manifest.txt 文件。
注意
如果你以 root 权限运行 make install 命令,那 install_manifest.txt 文件的权限将属于 root 用户,这会导致在普通用户权限下无法修改该文件
# 构建本例
# 构建并运行
$ mkdir build
$ cd build
$ cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/lib/ccache/cc
-- Check for working C compiler: /usr/lib/ccache/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/lib/ccache/c++
-- Check for working CXX compiler: /usr/lib/ccache/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/tartarus/cmake/cmake-examples/01-basic/E-installing/build
$ make
Scanning dependencies of target cmake_examples_inst # 共享库目标
[ 25%] Building CXX object CMakeFiles/cmake_examples_inst.dir/src/Hello.cpp.o
[ 50%] Linking CXX shared library libcmake_examples_inst.so
[ 50%] Built target cmake_examples_inst
Scanning dependencies of target cmake_examples_inst_bin # 可执行文件目标
[ 75%] Building CXX object CMakeFiles/cmake_examples_inst_bin.dir/src/main.cpp.o
[100%] Linking CXX executable cmake_examples_inst_bin
[100%] Built target cmake_examples_inst_bin
$ sudo make install
[ 50%] Built target cmake_examples_inst
[100%] Built target cmake_examples_inst_bin
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/cmake_examples_inst_bin
-- Set runtime path of "/usr/local/bin/cmake_examples_inst_bin" to ""
-- Installing: /usr/local/lib/libcmake_examples_inst.so
-- Up-to-date: /usr/local/include
-- Installing: /usr/local/include/installing
-- Installing: /usr/local/include/installing/Hello.h
-- Installing: /usr/local/etc/cmake-examples.conf
$ cat install_manifest.txt
/usr/local/bin/cmake_examples_inst_bin # 可执行目标文件,但是需要动态链接共享库libcmake_examples_inst.so
/usr/local/lib/libcmake_examples_inst.so # 动态共享库
/usr/local/include/installing/Hello.h
/usr/local/etc/cmake-examples.conf
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib cmake_examples_inst_bin
Hello Install!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 补充
# 修改默认安装路径
CMake 的默认安装位置由 CMAKE_INSTALL_PREFIX 指定,默认情况下是 /usr/local
如果你想修改默认安装位置为你的构建文件夹 ./build 下,你可以在 CMakeList.txt 添加任何目标前加上如下语句:
if( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT )
message(STATUS "Setting default CMAKE_INSTALL_PREFIX path to ${CMAKE_BINARY_DIR}/install")
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE STRING "The path to use for make install" FORCE)
endif()
2
3
4
注意
如果你修改 CMAKE_INSTALL_PREFIX 默认位置时,已经执行 cmake .. 完成了构建,那么你需要删除构建文件夹,重新构建。
# 卸载安装
CMake 默认情况下不提供 make uninstall 目标,一个简单的删除方法是使用 xargs :
sudo xargs rm < install_manifest.txt