Cmake中find_package命令的搜索模式之模块模式(Module mode)

Cmake中find_package命令的搜索模式之模块模式(Module mode),第1张

  前面介绍了 find_package 有两种搜索包的模式(参考 find_package介绍 ),本篇文章介绍其中的一种:模块模式( Module Mode )。在这种模式下,当调用 find_package 命令查找 <PackageName> 包的时候,实际上会去查找一个名为 Find<PackageName>cmake 的文件,这个文件的主要任务就是确定一个包是否可用,查找的结果会反映在变量 <PackageName>_FOUND 上供 find_package 的调用者使用。当找到可用的包,同时也会提供使用这个包所需要的变量、宏和导入目标(例如库文件)。

  前面已经介绍过使用系统提供的 FindLibLZMAcmake 来查找 LibLZMA 库,这个文件是 CMake 在安装的时候就提供的,位于 CMake 的安装目录之下。因此对于未提供该文件的第三方库,我们可以通过自己生成 Find<PackageName>cmake 来供 CMake 使用,接下来将介绍如何利用自己生成的 cmake 文件找到自己编写的库。

   模块模式 依赖另一个程序: pkg-config ,在继续往下之前,请参考 pkg-config用法详解 了解这个命令。

   Find<PackageName>cmake 文件承担了定义 <PackageName> 包相关的变量的作用,这些变量称作"标准变量"。一旦 find_package 调用成功,这些变量将返回给调用者使用,为了保证不同的包之间返回的变量不冲突,对编写的 Find<PackageName>cmake 返回的标准变量名称有如下约束:所有的变量都是以 PackageName_ 开头, PackageName 就是文件 Find<PackageName>cmake 中的 <PackageName> ,必须完全一致,大小写敏感。简单的列举几个变量定义如下,更多的变量定义见本文的 四、对标准变量名称的更多说明 :

  接下来我们来写一个 cmake 文件,假设我们的包名为 mymath ,该包提供一个 libmymatha 的库,其中包含一个 add 接口,简单计算两个整数的和并打印出结果(对这个库的更多信息可以参考 pkg-config用法详解 的 41 ~ 43 小节)。在编写 Findmymathcmake 之前,我们先来看下 cmake 文件的格式。

  假定我们使用的库 mymath 已经提供了 pc 文件,并能够通过 pkg-config 方式找到它(可以通过 pkg-onfig --list-all 查看到 mymath 库,参考 pkg-config用法详解 )。

  接下来我们来编写库 mymath 的 Findmymathcmake 文件,参照前面 cmake 文件说明,内容如下,示例只提供了库目录、库文件、头文件等少量变量信息:

  我们的测试文件 testcpp 如下:

  最后,在我们的 CMakeListstxt 来使用 find_package 来找到并使用 mymath 库

  在 CMakeListstxt 下执行 cmake 命令,此处为了演示,直接指定 CMAKE_MODULE_PATH 的值为当前的 cmake 所在路径,这样 find_package 命令会直接找到我们编写的 cmake 文件并读取其中的内容,编译并运行最终程序(只摘取了我们关注的显示信息):

cmake java是什么,让我们一起了解下?

cmake可以编译源代码、制作程序库、产生适配器(wrapper)、还可以用任意的顺序建构执行档。

如何使用cmake编译java工程?

cmake对编译Java代码和执行Java类文件的支持有限。

标准模块FindJava可用于查找本地机器上安装的JDK,标准模块UseJava为Java提供了一些功能,其中有一个函数add_jar来将Java源文件编译成jar文件。

这是一个小例子,演示如何使用add_jar给定Java示例源文件。

HelloWorldjava: public class HelloWorld {undefined public static void main(String[] args) {undefined Systemoutprintln("Hello, World!"); } }

以下CMake列表文件将编译HelloWorldjava到一个jar文件HelloWorldjar,并添加一个使用JVM运行该jar的CMake测试:

cmake_minimum_required (VERSION 28) find_package(Java REQUIRED) include(UseJava) enable_testing() project (HelloWorld) set(CMAKE_JAVA_COMPILE_FLAGS "-source" "16" "-target" "16") add_jar(HelloWorld HelloWorldjava) get_target_property(_jarFile HelloWorld JAR_FILE) get_target_property(_classDir HelloWorld CLASSDIR) message(STATUS "Jar file ${_jarFile}") message(STATUS "Class compiled to ${_classDir}") add_test(NAME TestHelloWorld COMMAND ${Java_JAVA_EXECUTABLE} -cp ${_jarFile} HelloWorld)

CMake变量CMAKE_JAVA_COMPILE_FLAGS可用于指定编译标志,作为副作用,add_jar命令将设置目标属性JAR_FILE和CLASSDIR,分别用于获取生成的jar文件和编译的类文件目录的路径。

由于调试需要因此研究了一下cmake这个夸平台的编译工具的使用方法

1本人的机器为ubuntu 1004,在连网的情况下直接在终端输入:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

root@zsh-linux:~#apt-get install cmake

安装完毕之后可以在/var/cache/apt/archives看到安装的deb文件

或者在cmake官网下载cmake for linux

此时有个注意点是建议下载 cmake-284targz 而不是

cmake-284-Linux-i386targz

下载完成后解压

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

root@zsh-linux:/opt#tar -zxvf cmake-284targz

然后 cd 到cmake-284目录下

root@zsh-linux:/opt/cmake-284#

root@zsh-linux:/opt/cmake-284# /bootstrap

root@zsh-linux:/opt/cmake-284# make

root@zsh-linux:/opt/cmake-284# make install

安装完毕后查看是否安装成功:

root@zsh-linux:/opt/cmake-284# cmake --version

cmake version 284

有以上信息表示安装cmake成功。

2cmake 的使用

(1)创建一个工程目录文件夹,然后创建一个helloc

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

#include<stdioh>

int main()

{

printf(“hello,this is my first using cmake project/n”);

return 0;

}

(2)然后创建一个build目录(用于编译生成的相应文件),与helloc目录同级

(3)编写CMakeListstxt内容如下:(于helloc目录同级)

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

cmake_minimum_required(VERSION 28)

PROJECT(cmake_test)

SET(SRC_LIST mainc)

INCLUDE_DIRECTORIES(/usr/include/glib)

MESSAGE(STATUS "This is BINARY dir "${HELLO_BINARY_DIR})

MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello ${SRC_LIST})

(4)进入build目录输入 cmake

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

root@zsh-linux:/home/cmake_test/build# cmake

若编译成功在build目录下会生成相应文件,其中有个makefile文件

有可能会出现问题:

CMAKE_CXX_COMPILER-NOTFOUND" was not found

解决方法:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

root@zsh-linux:/home/cmake_test/build# apt-get install g++

(可选)cmake -D CMAKE_CXX_COMPLIER=”g++”CMAKE -D CMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=”/usr/local”

(5)输入make 命令执行成功后在build目录下会看到可执行的hello

(6)/hello

输出 hello,this is my first usingcmake project。

注:这只适用于简单的工程,若复杂的工程项目请参考>

还可以在此参数后使用--target指定make的参数,cmake --build --target all即相当于:

使用configure_file命令,并且要把可执行文件生成目录加进来,因为生成的头文件就在该目录下。

需要新建一个project_confighin的文件,并在文件内添加如下两行:

上层目录的CMakeListstxt的文件需要增加如下内容,一是包含mymath的目录,二是将生成的mymath库链接到最后的可执行文件;可以通过一个开关来打开或者关闭,也可在cmake命令中加入-D参数来传入开关选项(宏定义)

通过option传递开关:

通过cmake命令传入:

CMake Tutorial

CMake Reference

定义程序编译规则

生成可执行文件的最简单版本的 CMakeListstxt

以上CMakeListstxt定义的编译规则是将源文件tutorialc编译成名为 Tutorial 的可执行文件。

一般用法是,新建一个文件夹,一般命名为 build ,在终端进入该文件夹,然后调用 cmake / , cmake 会在找到上级目录找到 CMakeListstxt ,生成 makefile 和一些其它文件。

在 makefile 所在目录,调用 make 命令,会根据 makefile 对程序进行编译生成。

给你的library定义一个带"IMPORTED" 属性的target,同时需要并为此定义lib和dll路径属性,需要区分debug和release。

链接此库用上面定义target的名字即可,这样会自动隐藏背后的不同版本的lib库文件。

在CMakeListstxt定义一个定制的build step来自动拷贝运行所需的dll文件:

通常,当你的项目集成了很多第三方库,以上这么干会把CMakeListstxt搞得很复杂,因此推荐得方式还是得写FindXXXcmake, 并在FindXXXcmake里创建对应的target,关于如何写可以参考 这篇文章 。

有些第三方库提供已编译好的库文件且是多个,这时候上面的target不再能拷贝dll,而且会报错unknwon target,对于这种第三方库的target得如下定义:

拷贝DLL文件的command得改成如下方式:

其实,Qt打包时候拷贝DLL也是同样这个做法:

注释:以 # 开头

cmake_minimum_required(VERSION 341) #设置Cmake最小版本

ADD_EXECUTABLE(exeNme 源码位置) #编译为可执行程序

add_library(libName STATIC 源码位置) # 生成静态链接库

add_library(libName SHARED 源码位置) # 生成动态链接库

SET(变量名 变量值) #设置变量

例如:

SET(srcDir mainc) 等价于 srcDir = "mainc"

SET(srcDir mainc democ testc) 等价于 srcDir = "mainc democ testc"

add_executable(debugger ${srcDir})#用 美元符号 使用变量

include_directories(路径)#设置头文件搜索路径,以CmakeListstxt所在目录为根目录

源文件中可以使用 <>来引入自己的头文件了,与引入标准库头文件保持格式的一致

例如:

include_directories(header) 则,源码中使用头文件的时候会从CmakeListstxt所在目录/header 中去寻找

add_subdirectory(mod1 lib)#执行 mod1/CmakeListstxt文件,并且把输出文件放在lib文件夹,同时会把lib文件夹作为链接库的搜索位置

link_directories(${PROJECT_SOURCE_DIR}/build/lib)#指明链接库的位置,如果程序要使用链接库,请一定要将此命令尽量写的靠前一些,要不然有时候会找不到链接库我也不知道为什么

target_link_libraries(exeName libName)#链接 libName,注意,链接之前要指明链接库的位置,如果libName代表动态链接库,则运行的时候需要把它拷贝到exeName同目录下

如果运行程序涉及到了动态链接库,则运行到时候需要把动态链接库拷贝到运行程序所在的文件夹

例如:

静态链接库 A

静态链接库 B

动态链接库 C

可执行程序 D

A依赖B和C

D依赖A,

则D运行的时候需要把B和C一起拷贝到其目录下注意,B是静态的,依然要拷贝过去

CMake部分构建变量列表:

Android Studio在 cmake_build_commandtxt 文件中保存用于执行CMake构建的构建参数。

Android Studio会为每个ABI和每个构建类型创建 cmake_build_commandtxt ,放置在如下目录:

示例:debug模式下的 armeabi-v7a 的CMake构建命令

这些构建参数是Gradle插件基于 buildgradle 的配置自动生成。

CMake构建参数列表:

在上面使用 add_library 来添加系统的预构建库。如果要添加其他的非系统的预构建库,比较FFmpeg的相关库,需要按如下格式:

如果要显示执行构建过程中的详细信息,比如为了得到更详细的出错信息。

自定义变量

常用变量

以上就是关于Cmake中find_package命令的搜索模式之模块模式(Module mode)全部的内容,包括:Cmake中find_package命令的搜索模式之模块模式(Module mode)、cmake java、linux cmakelist 怎么用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9445998.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-28
下一篇2023-04-28

发表评论

登录后才能评论

评论列表(0条)

    保存