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 mylibEXPORT mylib-targetsPUBLIC_HEADER DESTINATION includeARCHIVE DESTINATION libLIBRARY DESTINATION libRUNTIME DESTINATION bin)
install(EXPORT mylib-targetsNAMESPACE mylib::FILE mylib-config.cmakeDESTINATION 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 mylibEXPORT mylib-targetsPUBLIC_HEADER DESTINATION includeARCHIVE DESTINATION libLIBRARY DESTINATION libRUNTIME DESTINATION bin)

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

install(EXPORT mylib-targetsNAMESPACE mylib::FILE mylib-config.cmakeDESTINATION 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指令是如何运行的

cmake 生成供find_package使用的自定义模块相关推荐

  1. qt自定义插件creator不显示_让Qt Creator更懂我们的自定义模块

    用QML模块的方式组织软件是个不错的结构设计,笔者的QtQuick项目都会首先考虑QML模块的划分,然后以搭积木的方式完成最后的开发. Qt Creator是开发QtQuick程序的首先IDE,因为它 ...

  2. python 自定义模块加密_Python开发【第一篇】Python基础之自定义模块和内置模块...

    为什么要有模块,将代码归类.模块,用一砣代码实现了某个功能的代码集合. Python中叫模块,其他语言叫类库. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代 ...

  3. python-Day5-深入正则表达式--冒泡排序-时间复杂度 --常用模块学习:自定义模块--random模块:随机验证码--time datetime模块...

    正则表达式 语法: mport re #导入模块名 p= re.compile("^[0-9]") #生成要匹配的正则对象 , ^代表从开头匹配,[0-9]代表匹配0至9的任意一个 ...

  4. 使用Cmake生成跨平台项目编译解决方案

    项目最近有需求在windows下面运行,我花了几周时间将linux的服务器移植到windows下面,目前已经能够正常运行服务器,目前又有了新需求,两边的代码结构和组织是分开的,因此为了两边能够同步维护 ...

  5. 畅游Python 九:模块:自定义模块、第三方模块、内置模块

    用代码块实现某个功能的代码集合叫做模块. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才能 ...

  6. 如何在React Native中写一个自定义模块

    前言 在 React Native 项目中可以看到 node_modules 文件夹,这是存放 node 模块的地方,Node.js 的包管理器 npm 是全球最大的开源库生态系统.提到npm,一般指 ...

  7. python如何自定义模块_python自定义模块和开源模块使用方法

    模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...

  8. python 自定义模块_Python 自定义模块路径

    问题: 假设我们自己写了一个名为 log_config.py 的日志记录程序模块.此模块会被其他程序所引用,如下例子. import log_config logger = log_config.lo ...

  9. Nodejs模块、自定义模块、CommonJs的概念和使用

    场景 CommonJs JavaScript 是一个强大面向对象语言,它有很多快速高效的解释器.然而, JavaScript 标准定义的API 是为了构建基于浏览器的应用程序.并没有制定一个用于更广泛 ...

最新文章

  1. 架构设计复杂度的6个来源
  2. python代码大全p-Python网络爬虫实战项目代码大全(长期更新,欢迎补充)
  3. IOS开发基础之SQLite3数据库的使用增删改查
  4. linux应用开发:日志记录
  5. 2020年日历_2020年《故宫日历》发布:浓缩紫禁城600年沧桑
  6. ie浏览器速度提升设置 关闭网页多媒体方法
  7. 微软将发布新版Win10 可能以“新 Windows”之名公布
  8. pg库和mysql的优缺点_MySQL与PostgreSQL的实际性能比较
  9. openjdk7的ImageIO.read()导致jvm异常crash
  10. linux tomcat连接mysql步骤_Linux安装JDK 、TOMCAT 、MYSQL 步骤
  11. for each,for in,for of三者区别
  12. android adb日志过滤包名,adb过滤只查看某一个app的日志
  13. sca60c使用程序_使用PHP的SDO和SCA扩展
  14. Java内存模型——《深入理解Java虚拟机》笔记
  15. VMware安装win7操作系统
  16. LightGBM综述
  17. python中的开根、取整、求对数
  18. phpcustom数据库录入
  19. 数据流图详解(DFD)
  20. ubuntu 卡在waiting for unattended-upgr to exit的解决

热门文章

  1. office365在线安装太慢,换离线安装终于搞定
  2. JVM对象创建与内存分配机制学习总结
  3. 青藤云安全获六千万A轮融资 自适应安全平台营收过千万
  4. 一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
  5. <OS Concepts 9th> Chap 4 线程与并发
  6. 1400亿改造大明宫遗址区 西安将建城市中央公园
  7. ZZULIOJ 1800 少水群多刷题
  8. matlab绘制图形hold on_Matlab中的命令hold on hold off
  9. node.js基于微信小程序的校园失物招领毕业设计源码072343
  10. Sonar编译问题对应:File [...] can't be indexed twice.