关于cmake:CMakeListstxt系列1

33次阅读

共计 4496 个字符,预计需要花费 12 分钟才能阅读完成。

咱们晓得 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/dbzhang8…,大抵如下:
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 再次执行试试!!!
————————————————
版权申明:本文为 CSDN 博主「jelly_lzy」的原创文章,遵循 CC 4.0 BY-SA 版权协定,转载请附上原文出处链接及本申明。
原文链接:https://blog.csdn.net/u013896…

正文完
 0