Cmake之CMakeLists.txt

2023-05-16

        我们知道makefile是在Linux编译c或者c++代码的时候的一种脚本文件,但是每一个功能都要写一个makefile文件,这样如果这个工程很大,而且相关性比较强的话,makefile的书写就会变得相对繁琐,更要命的是如果以后需要添加新的功能或者是新人需要修改功能的话,看起来就会特别麻烦;因为介于此,cmake的出现就是为了解决这样的问题,cmake的入门相当容易,而且管理也特别方便简单,那我们开始吧。

        cmake的所有语句都写在一个CMakeLists.txt的文件中,CMakeLists.txt文件确定后,直接使用cmake命令进行运行,但是这个命令要指向CMakeLists.txt所在的目录,cmake之后就会产生我们想要的makefile文件,然后再直接make就可以编译出我们需要的结果了。更简单的解释就是cmake是为了生成makefile而存在,这样我们就不需要再去写makefile了,只需要写简单的CMakeLists.txt即可。

cmake的执行流程很简单,我们的重点是如何编写CMakeLists.txt文件呢,我们通过例子来学习cmake的语法。

例子从这篇文章中学习http://blog.csdn.net/dbzhang800/article/details/6314073,大致如下:

1、一个单文件的简单的例子

文件名字为main.c 内容如下:

#include <stdio.h>
int main()
{
    printf("Hello World Test!\n");
    return 0;
}

CMakeLists.txt文件内容如下:

project(hello_jelly)
set(APP_SRC main.c)
add_executable(${PROJECT_NAME} main.c)

#print message
message(${PROJECT_SOURCE_DIR})

解释代码:

第一个行project不是强制性的,最好加上,这会引入两个变量:

HELLO_BINARY_DIR, HELLO_SOURCE_DIR

同时也会定义两个等价的变量:

PROJECT_BINARY_DIR, PROJECT_SOURCE_DIR

外部编译要时刻区分这两个变量对应的目录

可以通过message进行输出

message(${PROJECT_SOURCE_DIR})

set 命令用来设置变量

add_exectuable 告诉工程生成一个可执行文件。

add_library 则告诉生成一个库文件。

CMakeList.txt 文件中,命令名字是不区分大小写的,而参数和变量是大小写相关的。

 

然后将以上两个文件放在统一目录下面,注意编译产生时候分为两种,一种是直接在当前源码目录执行cmake命令#cmake ./,但是这样会在当前目录下产生很多临时文件和目录,另一种方式就是在当前目录新建一个build目录,然后我门进入到build目录,执行命令cmake ../,这样产生的所有临时文件都会生成在build目录下,而不影响源码目录的代码,此处我们采用第二种方法。我们进入到build目录,执行命令#cmake ../,然后在当前目录可以看到文件如下

drwxrwxr-x 3 zqq zqq 4096 9月  28 17:12 CMakeFiles
-rw-rw-r-- 1 zqq zqq  993 9月  28 17:12 cmake_install.cmake
-rw-rw-r-- 1 zqq zqq 5479 9月  28 17:12 Makefile

最后再在此目录执行make即可生成相应的可执行程序。

2、多个源文件的操作

hello.h头文件内容如下

#ifndef JELLYHELLO
#define JELLYHELLO
void hello(const char* name);
#endif

hello.c文件内容

#include <stdio.h>
#include "hello.h"

void hello(const char* name)
{
    printf("Hello my name is %s\n",name);
}

main.c文件内容如下

#include <stdio.h>
#include "hello.h"

int main()
{
    printf("Hello World Test!\n");
    hello("jelly");
    return 0;
}

然后是CMakeLists.txt文件

project(hello_jelly)
set(APP_SRC main.c hello.c)
add_executable(${PROJECT_NAME} ${SRC_LIST})

#print message
message(${PROJECT_SOURCE_DIR})

然后保存使用上面的方法进行cmake和make,就可以生成需要的可执行文件

3、将hello.c生成一个库来调用

如果将hello生成成一个库来调用的话只需要在2的基础上修改一下CMakeLists.txt文件再进行编译即可

修改的CMakeLists.txt如下:

project(hello_jelly)
set(LIB_SRC hello.c)
set(APP_SRC main.c)
add_library(hello ${LIB_SRC})
add_executable(${PROJECT_NAME} ${APP_SRC})
target_link_libraries(${PROJECT_NAME} hello)

#print message
message(${PROJECT_NAME})

相比之下,我们只是添加了一个新的目标hello库,并将其链接到我们的demo程序

然后同样的方法进行cmake和make进行编译

4、工程分类文件夹编译

在前面,我们成功的使用了库,但是源代码都是在同一个路径下面,这样如果到时候代码量比较大的话,可能就会分类,形成多个文件夹,这样我们需要把代码分开放,此时我们需要些三个CMakeLists.txt文件,目录结构如下

drwxrwxr-x 2 zqq zqq 4096 9月  28 17:32 app
drwxrwxr-x 5 zqq zqq 4096 9月  28 17:12 build
-rw-rw-r-- 1 zqq zqq  487 9月  27 14:42 CMakeLists.txt
drwxrwxr-x 2 zqq zqq 4096 9月  28 17:19 libso

我们将main.c程序放在app目录下面,hello.c hello.h放在libso文件夹下面,然后该文件夹有一个CMakeLists.txt文件,app和libso文件夹下面也有CMakeLists.txt文件,这样就有三个CMakeLists.txt文件了,那么我们接下来来编辑这个三个文件吧。

首先是app文件夹的CMakeLists.txt

project(hello_jelly)
include_directories(${PROJECT_SOURCE_DIR}/../libso)

set(APP_SRC main.c)
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} helloso)

message(${PROJECT_SOURCE_DIR})

然后是libso文件夹的CMakeLists.txt,其中SHARED 表示是生成的动态库,如果把SHARED去掉的话就是生成静态库

project(helloso)

set(LIB_SRC hello.c)
add_library(${PROJECT_NAME} SHARED ${LIB_SRC})

最后是外面那个和app在同一目录下的CMakeLists.txt

cmake_minimum_required (VERSION 3.2)
project(jelly_cmake)

add_subdirectory(./app)
add_subdirectory(./libso)

其表示我们要到./app和./libso文件夹下面去寻找Cmake文件然后进行编译

最后我们在build目录下面去执行上面的命令编译即可编译出我们需要的可执行文件。

#cmake ../
#make

5、Cmake的install简单使用

我的理解cmake中的install其实就是一个将编译好的可执行文件或者是生成的库文件将它放到系统对应的位置,比如说可执行文件直接要放到bin目录下面,so库文件要放在对应的lib目录下面,我在上面的例子的基础上修改CMakeLists.txt文件,编辑完成后编译的步骤如下,就是多了个install步骤,这样我们就可以在Linux上面使用该执行文件,执行文件会去调用so库。

#cmake ../
#make
#make install

app目录修改的CMakeLists.txt如下:只是在之前的基础上加了最后install一行

project(hello_jelly)
include_directories(${PROJECT_SOURCE_DIR}/../libso)

set(APP_SRC main.c)
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} helloso)

message(${PROJECT_SOURCE_DIR})

install(TARGETS ${PROJECT_NAME} DESTINATION bin)

libso目录修改的CMakeLists.txt如下:只是在之前的基础上加了最后install一行

project(helloso)

set(LIB_SRC hello.c)
add_library(${PROJECT_NAME} SHARED ${LIB_SRC})

install(TARGETS ${PROJECT_NAME} DESTINATION ../lib)

在此需要解释下这个路径问题,install(TARGETS ${PROJECT_NAME} DESTINATION bin)这句话的意思是安装TARGERS hello_jelly这个可执行文件到${CMAKE_INSTALL_PREFIX}/bin目录下面,我测试打印我的${CMAKE_INSTALL_PREFIX}路径是/usr/local路径,bin前面不能有/,否则会是绝对路径,它不再会去获取${CMAKE_INSTALL_PREFIX}路径,

综上所述,可执行文件安装的路径是:

/usr/local/bin/

so库文件的安装路径是:

/usr/local/../lib/

最后执行那三个命令就完了,此时你可以在你的Linux系统里面的任何目录执行./hello_jelly

注:如果执行make install的时候出现错误,可以加上sudo再次执行试试!!!

相应的源码参考链接如下:

源码demo下载地址

如果后续还有其他的理解,我再在此更新!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cmake之CMakeLists.txt 的相关文章

  • CLion - 命令行程序参数

    当我分配给 运行 调试配置 程序参数 之类的 aaa bbb 然后打印它时 任何人都可以告诉我 JetBrains CLion 有什么问题吗 printf s n argv 1 我刚刚得到 aaa 而它必须是 aaa bbb 因为它们用双引
  • CMake:连续编译程序两次

    为了能够进行许多自动优化 我希望能够使用标志编译我的程序 fprofile generate首先 然后运行它生成配置文件 然后使用以下命令重新编译程序 fprofile use反而 这意味着我想连续编译我的程序两次 使用两个不同的CMAKE
  • 安装 EXPORT 需要子项目中的目标

    我正在尝试编写一个 cmake 脚本来安装我正在处理的项目 其中一部分是必要的install EXPORT LIB EXPORTS where LIB EXPORTS是我在各种项目中一直使用的 EXPORT 属性install TARGET
  • 为 CMake 中的子目录生成“干净”目标

    我想生成一个clean子目录的目标 我的项目结构是这样的 app A B lib A B C 有时我只想在 app A 上运行干净 并且不想清理库 是否可以告诉 CMake 生成clean每个目录的目标 或者像这样的自定义目标应用程序清理哪
  • 在生成器表达式中使用 cmake 选项

    我想在生成器表达式中使用 cmake 选项 为了打开某个编译标志 来自文档 https cmake org cmake help v3 10 manual cmake generator expressions 7 html我不清楚如何实现
  • 针对 dll/lib 的 cmake 链接

    我的 cmake 的输出是一个静态库 我正在这样创建它 add library myMainLib STATIC BACKEND SOURCES 当我尝试让 myMainLib 链接到第三方 lib dll 时 出现了问题 dll 文件将在
  • CMake 创建可执行文件时未定义的引用

    我是 CMake 新手 我正在尝试编译我的项目 该项目创建了一些静态库和一些可执行文件 下面是我拥有的文件结构的示例 PROJECT SRC 子项目 1该文件夹的 cpp 所有源文件 和CMakeLists txt 1 创建静态库 子项目
  • 使用 CMake 对 SDL 的未定义引用

    我正在使用 SDL v1 2 15 7 和 CMake 3 2 1 开发一个项目 在 h 文件中我添加了 include
  • CMake“无法运行 MSBUILD.exe”命令错误

    当我想为 opencv 3 3 0 创建 Visual Studio 15 2017 make 文件时 它给了我以下错误消息 error in configuration process project files maybe invali
  • Cygwin 下使用 CMake 编译库

    我一直在尝试使用 CMake 来编译 TinyXML 作为一种迷你项目 尝试学习 CMake 作为补充 我试图将其编译成动态库并自行安装 以便它可以工作 到目前为止 我已经设法编译和安装它 但它编译成 dll 和 dll a 让它工作的唯一
  • CMake 找不到请求的 Boost 库

    既然我已经浏览了其他人的解决方案几个小时 但找不到适合我的问题的正确答案 我想将我的具体问题带给您 我正在尝试使用 CMake 构建 vsomeip 为此 我之前构建了 boost 1 55 但是 我在 CMake 中收到以下错误 The
  • 了解 CMake 背后的目的[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我试图理解 CMake 背后的目的 为什么它被设计成现在这样 以下是我想回答的一些问题 为什么CMake会生成生成文件 https e
  • 如何在 CMake Makefile 中包含 OpenCV 库

    我希望你可以帮助我 我有一个简单的 CMakeLists txt 以便在 Leopard 10 5 8 上构建我的项目 我正在使用 CMake 2 8 1 目前这是代码 cmake minimum required VERSION 2 8
  • Cmake选项默认值

    如果我有一个 CMakeLists txt 文件 cmake minimum required VERSION 2 8 OPTION FOO Foo Option OFF MESSAGE FOO FOO 然后我调用 cmake 得到以下输出
  • CMake - 未定义参考

    我正在尝试将 gtest 包含到我的项目中 问题是我在 GTest 中收到未定义的引用错误 我正在尝试在 Gtest 中测试 Node 类 在节点的构造函数中 我使用类记录器 尽管我已将库记录器添加到 gtest target 中 但我仍然
  • 使用cmake交叉编译gRPC

    我正在尝试使用 cmake 交叉编译 gRPC 我实际上做到了 不幸的是 我的方法涉及在 CMakeLists txt 内部进行修改 问题是 当我尝试编译 gRPC 时 它使用的是他刚刚编译的 protobuffer 它无法在 x86 计算
  • Clion如何将文件添加到项目中

    这看起来真的很基本 如何将文件添加到项目中而无需手动编辑CMakeLists txt 例如另一个目录中的源文件 CLion 解析CMakeLists txt并使用它生成项目视图 但我相信将文件添加到项目的唯一方法是编辑CMakeLists
  • CMake、Exe找不到DLL

    所以我尝试在 Windows 上使用 cmake 设置一个项目 这就是我的项目结构 游戏引擎 git build include source testing CMakeLists txt 这个想法是 source 目录包含 GameEng
  • CMake第三方库安装

    我是编程新手 对于我的研究项目 我需要安装一个第三方库以便与 CMake 一起使用 GitHub项目 https github com cpp io2d P0267 RefImpl blob master BUILDING md 我在我的电
  • 如何在cmake中静态链接到glibc

    我正在尝试从 Fedora 构建一个可以在 RedHat 6 机器上运行的包 所以我需要构建和静态链接一些RedHat机器中不存在的库 我发现我可以你 static libgcc or static libstdc 与标准库的静态版本链接

随机推荐

  • PyTorch学习(7):学习率

    PyTorch学习 xff08 7 xff09 学习率 Pytorch官方文档 xff1a https pytorch cn readthedocs io zh latest Pytorch学习文档 xff1a https github c
  • PyTorch学习(8):模型保存和加载

    PyTorch学习 xff08 8 xff09 模型保存和加载 Pytorch官方文档 xff1a https pytorch cn readthedocs io zh latest Pytorch学习文档 xff1a https gith
  • PyTorch学习(9):实战

    PyTorch学习 xff08 9 xff09 实战 Pytorch官方文档 xff1a https pytorch cn readthedocs io zh latest Pytorch学习文档 xff1a https github co
  • oracle10g和11g版本自动undo管理模式下的手动问题

    糟心事情终于过了 xff0c 写写看PDF心得 参数 xff1a smu debug mode 来自 ITPUB博客 xff0c 链接 xff1a http blog itpub net 9606200 viewspace 2083963
  • PyTorch学习(10):训练技巧

    PyTorch学习 xff08 10 xff09 训练技巧 Pytorch官方文档 xff1a https pytorch cn readthedocs io zh latest 参考 xff1a https efficientdl com
  • 多个进程启动flask服务

    需求 xff1a 在不同的进程中分别启动flask服务 xff0c 或将其部署到不同的端口号上 span class token comment 导入flask类 span span class token keyword import s
  • python进程池Pool

    需求 xff1a 多进程 xff0c 加快程序运行 span class token comment 示例1 span span class token keyword from span multiprocessing span clas
  • Python进程池报错TypeError: can‘t pickle cv2.dnn_Net objects

    Python进程池报错 Traceback span class token punctuation span most recent call last span class token punctuation span span cla
  • Win10 RTX30系列 安装tensorflow1.15

    Win10 RTX30系列 安装tensorflow1 15 1 遇到的问题 xff1a 直接PiP安装 xff0c 能够安装完成 pip install tensorflow span class token operator span
  • Socket报错:BlockingIOError和greenlet.error

    报错 xff1a BlockingIOError Errno 11 Resource temporarily unavailable greenlet error cannot switch to a different thread Ex
  • 调研:AI货架识别

    综上 xff0c 为AI货架识别的调研结果 不是特别全面 xff0c 粗略了解
  • 基于改进SSIM算法的图像清晰度识别

    文章目录 基于改进SSIM算法的图像清晰度识别1 SSIM算法流程2 SSIM算法实现3 信息熵函数4 图像测试流程5 测试结果总结 基于改进SSIM算法的图像清晰度识别 转载 xff1a https www heywhale com mw
  • 基于DCT算法的图像模糊检测

    文章目录 基于DCT算法的图像模糊检测1 离散余弦变换DCT2 基于离散余弦变换DCT来估计图像模糊度的图像质量评价算法总结 基于DCT算法的图像模糊检测 转载 xff1a https yinguobing com dct blur ima
  • 标注工具——VGG Image Annotator (VIA)

    VGG Image Annotator VIA VGG Image Annotator VIA 是一款开源的图像标注工具 xff0c 由Visual Geometry Group开发 地址 xff1a http www robots ox
  • 0gR2最大保护模式DataGuard创建 (转载)

    10gR2最大保护模式DataGuard创建 一 设置主库归档 设置主库为force logging SQL gt alter database force logging 设置主库为归档模式 xff1a SQL gt archive lo
  • PyTorch学习:对比CV2和PyTorch的预处理

    验证预处理一致性 span class token keyword import span os span class token keyword import span cv2 span class token keyword impor
  • word中删除分节符时页面格式会发生改变

    word中删除分节符时页面格式会发生改变 问题 xff1a word xff08 word2007 word2010 word2013 word2016等 xff09 删除分节符 xff08 下一页 xff09 以后 xff0c 分节符以前
  • Ubuntu终端代理工具——proxychains

    安装proxychains sudo apt install proxychains 配置proxychains 打开proxychains配置文件 sudo vim etc proxychains conf 在proxychains co
  • 只是因为多看了你一眼

    不得已的选择 高考 xff0c 应该是每个学生心中最难忘的一场考试了 xff0c 在过去十二年里有无数场大大小小的考试 xff0c 无论你过去是多么的优秀 xff0c 还是多么的差劲 xff0c 只要这一次你 xff0c 赢了就是赢了 xf
  • Cmake之CMakeLists.txt

    我们知道makefile是在Linux编译c或者c 43 43 代码的时候的一种脚本文件 xff0c 但是每一个功能都要写一个makefile文件 xff0c 这样如果这个工程很大 xff0c 而且相关性比较强的话 xff0c makefi