前言
從上一篇的文章中,相信大家也了解了CMake
這個(gè)東西,但是呢它不是只是看一下就能會(huì)的,這種東西還是要實(shí)踐才能學(xué)會(huì),那么如果你已經(jīng)實(shí)踐過(guò)了,就會(huì)體會(huì)到上一篇文章在實(shí)際中使用到底是多么的難搞,比如:
- 生成很多垃圾文件,這是我的第一個(gè)體會(huì)….
- 需要手動(dòng)去指定編譯的文件
- 無(wú)法指定編譯器,編譯選項(xiàng)等等很多東西….
- 如果有子目錄也不能完全適用….
- 以及一些其他的問(wèn)題….
總的來(lái)說(shuō)就是在真正項(xiàng)目中壓根就沒法適用的工程,那為什么我要寫呢,因?yàn)槟鞘俏覍W(xué)習(xí)的過(guò)程,總不能一口吞下一個(gè)大胖子是不是,接下來(lái)的一系列文章我就會(huì)讓CMake
變得能在實(shí)際中使用,越來(lái)越自動(dòng)化,更方便構(gòu)建。。。
外部構(gòu)建
第一個(gè)問(wèn)題,在運(yùn)行cmake .
后會(huì)產(chǎn)生很多垃圾文件,那么我們可以讓它在一個(gè)build目錄下去編譯,生成的垃圾文件放在這個(gè)目錄下就好了,不需要的時(shí)候直接清除即可。
可能有人會(huì)問(wèn),它不能像Makefile一樣直接make clean
或者make distclean
清除編譯的垃圾文件嗎,我當(dāng)時(shí)學(xué)的時(shí)候也谷歌過(guò),但是,很遺憾沒有,使用我才讓它產(chǎn)生的垃圾文件放在build目錄下,其實(shí)不能說(shuō)是垃圾文件,只不過(guò)是一些中間文件,記錄某些東西的,我用不上它,所以認(rèn)為是垃圾…僅此而已。
對(duì)此官方的解釋是:
CMakeLists.txt 可以執(zhí)行腳本并通過(guò)腳本生成一些臨時(shí)文件,但是卻沒有辦法來(lái)跟蹤這些臨時(shí)文件到底是哪些,因此,沒有辦法提供一個(gè)可靠的 clean 方案。
那怎么辦呢?很簡(jiǎn)單,從CMake
的語(yǔ)法我們就知道,它在構(gòu)建的時(shí)候指定了PATH
,也就是頂層CMakeLists.txt
入口的路徑。
cmake PATH
那么很顯然,它可以是相對(duì)路徑而不是絕對(duì)路徑,畢竟點(diǎn)‘.’
表示當(dāng)前路徑, 點(diǎn)點(diǎn)‘..’
表示上一級(jí)路徑,那么我們可以新建一個(gè)build目錄,然后在build目錄下去運(yùn)行:
cmake ..
這在CMake
中稱之為外部構(gòu)建(out-of-source build),而 CMake
強(qiáng)烈推薦的就是外部構(gòu)建!
我自己也寫了個(gè)build的腳本,內(nèi)容非常簡(jiǎn)單,主要做兩件事:
- 創(chuàng)建一個(gè)build目錄(存在就不會(huì)重新創(chuàng)建的)
- 進(jìn)入build目錄
- 然后外部構(gòu)建cmake
- 生成Makefile文件后運(yùn)行make命令編譯
#!/bin/bash
mkdir -p build
cd build
cmake ..
make
因此在編譯的時(shí)候直接運(yùn)行這個(gè)腳本即可,生成的內(nèi)容全部都在build目錄下。
- 這是原始目錄
.
├── build.sh
├── CMakeLists.txt
└── main.c
0 directories, 3 files
編譯后在build目錄下生成很多文件,包括 Makefile、section2(可執(zhí)行程序)
等
CMakeCache.txt CMakeFiles cmake_install.cmake Makefile section2
補(bǔ)充一點(diǎn),如果你想看到cmake生成的垃圾文件比你源碼還多的時(shí)候,你就會(huì)愛死外部構(gòu)建這種騷操作了~
自動(dòng)查找源碼
不得不說(shuō),cmake是個(gè)很好的自動(dòng)化構(gòu)建工具,既然是自動(dòng)化,那么很的東西都是自動(dòng)的,比如查找源碼,cmake就提供查找源碼的命令:
aux_source_directory(<dir> <variable>)
它的主要作用就是: 查找在某個(gè)路徑下的所有源文件 ,注意,是所有源碼文件,當(dāng)你的目錄下有很多個(gè)源碼文件的時(shí)候,他就主動(dòng)去查找了,哦,當(dāng)然,它也只會(huì)查找源碼文件,比如*.c 、 *.cpp 、*.cc
啦,反正只要是源碼就可以了,但是什么txt 、 *.h
文件這些它是不會(huì)記錄下來(lái)的。
dir
:指定的目錄(可以是絕對(duì)路徑也可以是相對(duì)路徑)variable
:將輸出結(jié)果列表儲(chǔ)存在指定的
變量中。
反正這個(gè)命令就很方便,我在某個(gè)目錄下有啥源碼文件,我都會(huì)被記錄到
變量,然后在CMake
直接使用即可。當(dāng)然后續(xù)也有其他的命令去找源碼文件,一口吃不了一個(gè)大胖子,先了解這個(gè)先,后續(xù)慢慢學(xué)習(xí)~
變量
在CMake
中,變量是十分常見的,我正在就簡(jiǎn)單講解下基本的語(yǔ)法吧:
定義變量常用的函數(shù)是:
set(VARIABLE_NAME VARIABLE)
取消定義變量是
unset(VARIABLE_NAME )
VARIABLE_NAME
:變量名字VARIABLE
:變量的值
變量的的值始終是string(字符串)
類型,變量名字是區(qū)分大小寫的,一般變量命名還是正常點(diǎn)比較好,別搞太多亂七八糟的特殊符號(hào),只要數(shù)字、字母,下劃線"_"
、橫線"-"
就差不多了,變量的作用域也是有全局與局部之分,與C語(yǔ)言、Java都差不多,我也不多說(shuō)了。我的例程中全局變量是全部大寫,局部變量是全小寫
的,也是比較好區(qū)分。
變量引用的形式為${variable_name}
,變量引用被變量的值替換,或者如果變量沒有被設(shè)置,則由空字符串替換。變量引用可以嵌套,例如${outer_${inner_variable}veriable}
;環(huán)境變量引用的形式為$ENV{VARIABLE}
,并在相同的上下文中作為正常變量引用。
打印日志
在CMake構(gòu)建的時(shí)候,你可能不知道某些變量是啥內(nèi)容,那么就在終端打印出來(lái)看看就好了,這根我們寫代碼中的printf函數(shù)差不多,給直接打一串字符串出來(lái)瞧瞧….
message([ "message to display" ...)
首先呢,
是指定消息的類型:
(無(wú))
= 重要消息;STATUS
= 非重要消息;WARNING
= CMake 警告, 會(huì)繼續(xù)執(zhí)行;AUTHOR_WARNING
= CMake 警告 (dev), 會(huì)繼續(xù)執(zhí)行;SEND_ERROR
= CMake 錯(cuò)誤, 繼續(xù)執(zhí)行,但是會(huì)跳過(guò)生成的步驟;FATAL_ERROR
= CMake 錯(cuò)誤, 終止所有處理過(guò)程;
正常情況下我都是輸出一些狀態(tài)信息——STATUS
,打印個(gè)變量啦,打印下代碼的執(zhí)行順序啦等等….
后面就是有些字符串信息了,變量在這里直接引用就好,畢竟變量本身就是字符串….
section3
給出個(gè)實(shí)例代碼:
當(dāng)前目錄存在2個(gè)c文件,分別是main.c
、power.c
就是簡(jiǎn)單計(jì)算x的y次方,純粹是個(gè)demo,我自己也懶得寫,并不是因?yàn)榇a有多高深,所以這代碼我是從網(wǎng)上找的,來(lái)自@潘偉洲大神的cmake測(cè)試代碼:https://github.com/wzpan/cmake-demo。
- main.c
#include
#include
#include "power.h"
int main(int argc, char *argv[])
{
if (argc < 3){
printf("Usage: %s base exponent \\n", argv[0]);
return 1;
}
double base = atof(argv[1]);
int exponent = atoi(argv[2]);
double result = power(base, exponent);
printf("%g ^ %d is %g\\n", base, exponent, result);
return 0;
}
- power.c
double power(double base, int exponent)
{
int result = base;
int i;
if (exponent == 0) {
return 1;
}
for(i = 1; i < exponent; ++i){
result = result * base;
}
return result;
}
然后就是CMakeLists.txt
文件:
# CMake 最低版本號(hào)要求
cmake_minimum_required (VERSION 2.8)
# 項(xiàng)目信息
project (section3)
# 查找當(dāng)前目錄下的所有源文件
# 并將名稱保存到 DIR_SRCS 變量
aux_source_directory(. DIR_SRCS)
# 指定生成目標(biāo)
add_executable(section3 ${DIR_SRCS})
相比于上一篇文章,我這個(gè)CMakeLists.txt
文件只是添加了aux_source_directory
命令去自動(dòng)掃描當(dāng)前目錄下的源碼文件,并且保存到DIR_SRCS
變量中,僅此而已!!
然后在add_executable
命令中,用${DIR_SRCS}
變量代替指定的源碼文件source1 source2 ... sourceN
,當(dāng)然你也可以打印一下${DIR_SRCS}
變量到底保存了什么,如果不出意外的話,它保存的就是./main.c; ./power.c
,表示的是當(dāng)前目錄下的main.c
、power.c
這兩個(gè)文件,而分號(hào)代表它是一個(gè)list,后續(xù)會(huì)講解怎么去提取list的內(nèi)容….
message(STATUS "${DIR_SRCS}")
然后用外部構(gòu)建的方式去編譯代碼:
jie@pc:~/github/cmake/section3$ ./build.sh
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jie/github/cmake/section3/build
Scanning dependencies of target section3
[ 33%] Building C object CMakeFiles/section3.dir/main.c.o
[ 66%] Building C object CMakeFiles/section3.dir/power.c.o
[100%] Linking C executable section3
[100%] Built target section3
很明顯生成了正確可執(zhí)行文件~
代碼下載
https://github.com/jiejieTop/cmake
-
Build
+關(guān)注
關(guān)注
0文章
26瀏覽量
12259 -
編譯
+關(guān)注
關(guān)注
0文章
676瀏覽量
33720 -
CMake
+關(guān)注
關(guān)注
0文章
28瀏覽量
1442
發(fā)布評(píng)論請(qǐng)先 登錄
Linux中CMake的使用3-不同目錄多個(gè)源文件

cmake是什么?cmake的特性和編譯原理(cmake原理和cmake編譯過(guò)程)

Windows下編譯工具CMake的安裝和最簡(jiǎn)使用

Cmake學(xué)習(xí)的總結(jié)(二)
cmake管理配置ROOT項(xiàng)目的方法

如何使用CMake工具套件構(gòu)建CUDA應(yīng)用程序

RT-Thread V4.1.0新特性CMake介紹與構(gòu)建CMake工程
RT-Thread 4.1.0的CMake構(gòu)建教程
CMake的實(shí)戰(zhàn)教程-1

CMake的實(shí)戰(zhàn)教程-2
在Linux下如何使用CMake編譯程序

CMake構(gòu)建后的項(xiàng)目結(jié)構(gòu)解析

評(píng)論