CMake之install方法的使用

所有相关代码,可以访问我的github项目,欢迎star。

本文主要介绍如何将项目生成的库文件、头文件、可执行文件或相关文件等安装到指定位置(系统目录,或发行包目录)。在cmake中,这主要是通过install方法在CMakeLists.txt中配置,make install命令安装相关文件来实现的。

编写一个简单的库

编写一个计算整数和浮点数之和的库函数mymath

mymath.h

#ifndef MYMATH_H
#define MYMATH_H

int add(int, int);
double add(double, double);
#endif

mymath.cc

#include "mymath.h"

int add(int a, int b){
    return a+b;
}

double add(double a, double b){
    return a+b;
}

可执行程序mymathApp.cc

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

using namespace std;

int main(int argc, char const *argv[])
{
    double a = add(1.1, 1.1);
    int b = add(1, 1);
    cout << "1.1加1.1等于" << a <<endl;
    cout << "1加1等于" << b <<endl;
    return 0;
}

在CMakeLists中添加配置

cmake_minimum_required(VERSION 3.0)
project(Installation VERSION 1.0)

# 如果想生成静态库,使用下面的语句
# add_library(mymath mymath.cc)
# target_include_directories(mymath PUBLIC ${CMAKE_SOURCE_DIR}/include)

# 如果想生成动态库,使用下面的语句
add_library(mymath SHARED mymath.cc)
target_include_directories(mymath PRIVATE  ${CMAKE_SOURCE_DIR}/include)
set_target_properties(mymath PROPERTIES PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/include/mymath.h)

# 生成可执行文件
add_executable(mymathapp mymathApp.cc)
target_link_libraries(mymathapp mymath)
target_include_directories(mymathapp PRIVATE ${CMAKE_SOURCE_DIR}/include)

接下来我们为生成的target配置安装目录。install方法的基础用法如下

install(TARGETS MyLib
        EXPORT MyLibTargets 
        LIBRARY DESTINATION lib  # 动态库安装路径
        ARCHIVE DESTINATION lib  # 静态库安装路径
        RUNTIME DESTINATION bin  # 可执行文件安装路径
        PUBLIC_HEADER DESTINATION include  # 头文件安装路径
        )

LIBRARY, ARCHIVE, RUNTIME, PUBLIC_HEADER是可选的,可以根据需要进行选择。 DESTINATION后面的路径可以自行制定,根目录默认为CMAKE_INSTALL_PREFIX,可以试用set方法进行指定,如果使用默认值的话,Unix系统的默认值为 /usr/local, Windows的默认值为 c:/Program Files/${PROJECT_NAME}。比如字linux系统下若LIBRARY的安装路径指定为lib,即为/usr/local/lib。所以要安装mymath mymathapp我们可以这样写

# 将库文件,可执行文件,头文件安装到指定目录
install(TARGETS mymath mymathapp
        EXPORT MyMathTargets
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib
        RUNTIME DESTINATION bin
        PUBLIC_HEADER DESTINATION include
        )

他人如果使用我们编写的函数库,安装完成后,希望可以通过find_package方法进行引用,这时我们需要怎么做呢。

首先我们需要生成一个MyMathConfigVersion.cmake的文件来声明版本信息

# 写入库的版本信息
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
        MyMathConfigVersion.cmake
        VERSION ${PACKAGE_VERSION}
        COMPATIBILITY AnyNewerVersion  # 表示该函数库向下兼容
        )

其中PACKAGE_VERSION便是我们在CMakeLists.txt开头project(Installation VERSION 1.0)中声明的版本号

第二步我们将前面EXPORT MyMathTargets的信息写入到MyLibTargets.cmake文件中, 该文件存放目录为${CMAKE_INSTALL_PREFIX}/lib/cmake/MyMath

install(EXPORT MyMathTargets
        FILE MyLibTargets.cmake
        NAMESPACE MyMath::
        DESTINATION lib/cmake/MyLib
        )

最后我们在源代码目录新建一个MyMathConfig.cmake.in文件,用于获取配置过程中的变量,并寻找项目依赖包。如果不一来外部项目的话,可以直接include MyMathTargets.cmake文件

include(CMakeFindDependencyMacro)

# 如果想要获取Config阶段的变量,可以使用这个
# set(my-config-var @my-config-var@)

# 如果你的项目需要依赖其他的库,可以使用下面语句,用法与find_package相同
# find_dependency(MYDEP REQUIRED)

# Any extra setup

# Add the targets file
include("${CMAKE_CURRENT_LIST_DIR}/MyMathTargets.cmake")

最后在CMakeLists.txt文件中,配置生成MyMathTargets.cmake文件,并一同安装到${CMAKE_INSTALL_PREFIX}/lib/cmake/MyMath目录中。

configure_file(MyMathConfig.cmake.in MyMathConfig.cmake @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/MyMathConfig.cmake"
                "${CMAKE_CURRENT_BINARY_DIR}/MyMathConfigVersion.cmake"
        DESTINATION lib/cmake/MyMath
        )

最后我们在其他项目中,就可以使用

find_package(MyMath 1.0)
target_linked_library(otherapp MyMath::mymath)

来引用我们的函数库了。

编辑于 2020-01-15 22:56