cmake 生成供find_package使用的自定义模块

cmake中经常使用find_package寻找模块,使用起来非常方便.find_package的原理是什么呢?如何自己写个模块提供给别人使用?如果别人希望用find_package的形式使用你的模块中的库,我该如何用cmake写这个库呢?
下面用一个例子来说明:
myapp程序通过find_package调用mylib中的库

1.myapp工程

myapp工程目录如下
.
├── CMakeLists.txt
└── myapp.c

其中CMakeLists.txt

project(myapp)
cmake_minimum_required(VERSION 2.8)
SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/home/rootroot/newworkspace/mylib/install")
find_package(mylib REQUIRED)
add_executable(${PROJECT_NAME} myapp.c)
target_link_libraries(${PROJECT_NAME} mylib::mylib)

通过find_package来寻找我的自定义模块mylib,SET(CMAKE_PREFIX_PATH)告诉cmake在我指定的位置寻找模块,我的mylib安装在/home/rootroot/newworkspace/mylib/install路径下.
myapp.c代码如下

#include<stdio.h>
#include <mylib.h>
int main()
{
    hello();
    return 0;
}

2.mylib工程

最后生成的mylib工程结构如下
.
├── CMakeLists.txt
├── include
│ └── mylib.h
├── install
│ ├── include
│ │ └── mylib.h
│ └── lib
│ ├── cmake
│ │ └── mylib
│ │ ├── mylib-config.cmake
│ │ └── mylib-config-noconfig.cmake
│ ├── libmylib.a

└── mylib.c

其中install是要myapp需要调用的库文件夹.mylib-config.cmake是由cmake自动生成的文件.findpack需要找的.cmake文件才能寻找包成功.

mylib.c代码如下

#include<stdio.h>
#include"mylib.h"
void hello()
{
      printf("hello");
}

mylib.h

#ifndef MYLIB_H
#define MYLIB_H
#include <stdio.h>
void hello();
#endif

关键是如何写CMakeLists.txt,要能生成find_package能够找到的模块(包).
CMakeLists.txt代码如下:

cmake_minimum_required(VERSION 2.8)
add_library(mylib mylib.c include/mylib.h)
SET(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install)
target_include_directories(mylib PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "include/mylib.h")
install(TARGETS mylib
    EXPORT mylib-targets
    PUBLIC_HEADER DESTINATION include
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    RUNTIME DESTINATION bin)
install(EXPORT mylib-targets
    NAMESPACE mylib::
    FILE mylib-config.cmake
    DESTINATION lib/cmake/mylib)

分句解析:
add_library(mylib mylib.c include/mylib.h)
表示将mylib.c编译成mylib链接库文件
SET(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install)
表示将编译好的库文件安装在当前工程的install文件夹下.

target_include_directories(mylib PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)

BUILD_INTERFACE表示源文件夹在哪
INSTALL_INTERFACE表示安装文件夹在哪

set_target_properties(mylib PROPERTIES PUBLIC_HEADER "include/mylib.h")

表示安装的头文件名称是mylib.h.

install(TARGETS mylib
    EXPORT mylib-targets
    PUBLIC_HEADER DESTINATION include
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    RUNTIME DESTINATION bin)

这是安装的一些属性:注意EXPORT选项标识了库文件为供别的程序使用的,LIBRARY DESTINATION 表示库文件的目标文件夹lib 的路径为相对于CMAKE_INSTALL_PREFIX的路径.
其中

install(EXPORT mylib-targets
    NAMESPACE mylib::
    FILE mylib-config.cmake
    DESTINATION lib/cmake/mylib)

安装的时候还需要生成 mylib-config.cmake文件才能让find_package找到.
注意.cmake文件必须是命名如mylib-config.cmake或者
MylibConfig.cmake才能找到.

3编译运行

先编译安装mylib
在mylib文件夹下

mkdir build
cd build
cmake ..
make
make install

在myapp文件夹下

mkdir build
cd build
cmake ..
make
./myapp

显示
hello

最后,为了方便大家理解,将代码打包上传,欢迎大家下载
https://download.csdn.net/download/ktigerhero3/10773044

参考文献
https://stackoverflow.com/questions/31537602/how-to-use-cmake-to-find-and-link-to-a-library-using-install-export-and-find-pac
https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#package-configuration-file
cmake的find_package指令是如何运行的

  • 16
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,这是一个关于使用 CMake 生成其他 CMake 文件 `find_package()` 的库文件的问题。下面是一个简单的步骤: 1. 编 CMakeLists.txt 文件,定义要生成的库文件。 ```cmake # 定义要生成的库文件名称和源文件 add_library(mylib mylib.cpp) # 定义头文件路径 target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) # 导出库文件的头文件和库文件 include(GNUInstallDirs) install(TARGETS mylib EXPORT mylib-config LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(EXPORT mylib-config NAMESPACE mylib:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mylib FILE mylib-config.cmake) ``` 2. 在 CMakeLists.txt 文件中设置库文件的属性。 ```cmake # 设置库文件属性 set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 1 PUBLIC_HEADER include/mylib.h ) ``` 3. 生成配置文件 ```cmake # 生成配置文件 include(CMakePackageConfigHelpers) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/mylib-config-version.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) configure_package_config_file( "${CMAKE_CURRENT_LIST_DIR}/mylib-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/mylib-config.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mylib" ) # 安装配置文件 install( FILES "${CMAKE_CURRENT_BINARY_DIR}/mylib-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/mylib-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mylib" ) ``` 4. 在其他 CMakeLists.txt 文件中使用生成的库文件。 ```cmake # 查找库文件 find_package(mylib REQUIRED) # 添加库文件路径 link_directories(${mylib_LIBRARY_DIRS}) # 添加库文件 add_executable(myapp main.cpp) target_link_libraries(myapp ${mylib_LIBRARIES}) ``` 以上就是一个简单的使用 CMake 生成其他 CMake 文件 `find_package()` 的库文件的步骤。希望能够帮到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值