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 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使用的自定义模块相关推荐
- qt自定义插件creator不显示_让Qt Creator更懂我们的自定义模块
用QML模块的方式组织软件是个不错的结构设计,笔者的QtQuick项目都会首先考虑QML模块的划分,然后以搭积木的方式完成最后的开发. Qt Creator是开发QtQuick程序的首先IDE,因为它 ...
- python 自定义模块加密_Python开发【第一篇】Python基础之自定义模块和内置模块...
为什么要有模块,将代码归类.模块,用一砣代码实现了某个功能的代码集合. Python中叫模块,其他语言叫类库. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代 ...
- python-Day5-深入正则表达式--冒泡排序-时间复杂度 --常用模块学习:自定义模块--random模块:随机验证码--time datetime模块...
正则表达式 语法: mport re #导入模块名 p= re.compile("^[0-9]") #生成要匹配的正则对象 , ^代表从开头匹配,[0-9]代表匹配0至9的任意一个 ...
- 使用Cmake生成跨平台项目编译解决方案
项目最近有需求在windows下面运行,我花了几周时间将linux的服务器移植到windows下面,目前已经能够正常运行服务器,目前又有了新需求,两边的代码结构和组织是分开的,因此为了两边能够同步维护 ...
- 畅游Python 九:模块:自定义模块、第三方模块、内置模块
用代码块实现某个功能的代码集合叫做模块. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才能 ...
- 如何在React Native中写一个自定义模块
前言 在 React Native 项目中可以看到 node_modules 文件夹,这是存放 node 模块的地方,Node.js 的包管理器 npm 是全球最大的开源库生态系统.提到npm,一般指 ...
- python如何自定义模块_python自定义模块和开源模块使用方法
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- python 自定义模块_Python 自定义模块路径
问题: 假设我们自己写了一个名为 log_config.py 的日志记录程序模块.此模块会被其他程序所引用,如下例子. import log_config logger = log_config.lo ...
- Nodejs模块、自定义模块、CommonJs的概念和使用
场景 CommonJs JavaScript 是一个强大面向对象语言,它有很多快速高效的解释器.然而, JavaScript 标准定义的API 是为了构建基于浏览器的应用程序.并没有制定一个用于更广泛 ...
最新文章
- 架构设计复杂度的6个来源
- python代码大全p-Python网络爬虫实战项目代码大全(长期更新,欢迎补充)
- IOS开发基础之SQLite3数据库的使用增删改查
- linux应用开发:日志记录
- 2020年日历_2020年《故宫日历》发布:浓缩紫禁城600年沧桑
- ie浏览器速度提升设置 关闭网页多媒体方法
- 微软将发布新版Win10 可能以“新 Windows”之名公布
- pg库和mysql的优缺点_MySQL与PostgreSQL的实际性能比较
- openjdk7的ImageIO.read()导致jvm异常crash
- linux tomcat连接mysql步骤_Linux安装JDK 、TOMCAT 、MYSQL 步骤
- for each,for in,for of三者区别
- android adb日志过滤包名,adb过滤只查看某一个app的日志
- sca60c使用程序_使用PHP的SDO和SCA扩展
- Java内存模型——《深入理解Java虚拟机》笔记
- VMware安装win7操作系统
- LightGBM综述
- python中的开根、取整、求对数
- phpcustom数据库录入
- 数据流图详解(DFD)
- ubuntu 卡在waiting for unattended-upgr to exit的解决
热门文章
- office365在线安装太慢,换离线安装终于搞定
- JVM对象创建与内存分配机制学习总结
- 青藤云安全获六千万A轮融资 自适应安全平台营收过千万
- 一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
- <OS Concepts 9th> Chap 4 线程与并发
- 1400亿改造大明宫遗址区 西安将建城市中央公园
- ZZULIOJ 1800 少水群多刷题
- matlab绘制图形hold on_Matlab中的命令hold on hold off
- node.js基于微信小程序的校园失物招领毕业设计源码072343
- Sonar编译问题对应:File [...] can't be indexed twice.