1. 程式人生 > >CMake快速入門教程:實戰

CMake快速入門教程:實戰

轉自http://blog.csdn.net/ljt20061908/article/details/11736713

0. 前言
    一個多月前,由於工程專案的需要,匆匆的學習了一下cmake的使用方法,現在有時間拿出來整理一下。本文假設你已經學會了cmake的使用方法,如果你還不會使用cmake,請參考相關資料之後再繼續向下看。
    本文中介紹的是生成可執行程式的方法和步驟,生成動態庫和靜態庫的方法與此有所不同,隨後會介紹動態庫和靜態庫專案中cmake的編寫方法。
    本文參考《CMake Practice》這篇文章完成,旨在指導使用者快速使用CMake,如果需要更詳細的內容,請通讀《CMake Practice》這篇文章。下載路徑:

http://sewm.pku.edu.cn/src/paradise/reference/CMake%20Practice.pdf
1. 專案目錄結構
    我們專案的名稱為CRNode,假設我們專案的所有檔案存放再~/workspace/CRNode,之後沒有特殊說明的話,我們所指的目錄都以此目錄為相對路徑。
    我們的目錄結構如下:

  1. ~/workspace/CRNode  
  2.   ├─ src   
  3.   │  ├─ rpc   
  4.   │  │  ├─ CRMasterCaller.h  
  5.   │  │  ├─ CRMasterCaller.cc  
  6.   │  │  ├─ CRNode.h  
  7.   │  │  ├─ CRNode.cc  
  8.   │  │  ├─ Schd_constants.h  
  9.   │  │  ├─ Schd_constants.cc  
  10.   │  │  ├─ CRMaster.h  
  11.   │  │  ├─ CRMaster.cc  
  12.   │  │  ├─ CRNode_server.skeleton.h  
  13.   │  │  ├─ CRNode_server.skeleton.cc  
  14.   │  │  ├─ Schd_types.h  
  15.   │  │  └─ Schd_types.cc  
  16.   │  ├─ task   
  17.   │  │  ├─ TaskExecutor.h  
  18.   │  │  ├─ TaskExecutor.cc  
  19.   │  │  ├─ TaskMonitor.h  
  20.   │  │  └─ TaskMonitor.cc  
  21.   │  ├─ util   
  22.   │  │  ├─ Const.h  
  23.   │  │  ├─ Const.cc  
  24.   │  │  ├─ Globals.h  
  25.   │  │  ├─ Globals.cc  
  26.   │  │  ├─ Properties.h  
  27.   │  │  ├─ Properties.cc  
  28.   │  │  ├─ utils.h  
  29.   │  │  └─ utils.cc  
  30.   │  ├─ main.cc  
  31.   │  └─ CMakeLists.txt  
  32.   ├─ doc  
  33.   │  └─ crnode.txt  
  34.   ├─ COPYRIGHT  
  35.   ├─ README  
  36.   ├─ crnode.sh  
  37.   └─ CMakeLists.txt  

    其中,src存放原始碼檔案和一個CMakeLists.txt檔案,CMakeLists檔案的編寫我們稍候介紹;doc目錄中存放專案的幫助文件,該文件以及COPYRIGHT和README一起安裝到/usr/share/doc/crnode目錄中;COPYRIGHT檔案存放專案的版權資訊,README存放一些說明性文字;crnode.sh存放CRNode的啟動命令;CMakeLists.txt檔案稍候介紹。
    除此之外,專案還依賴兩個外部庫:Facebook開發的thrift庫,其標頭檔案存放在/usr/include/thrift目錄中;log4cpp庫,其標頭檔案存放再/usr/include下。
2. CMakeLists.txt檔案
    本工程中使用了兩個CMakeLists.txt檔案,分別專案的根目錄(即~/workspace/CRNode目錄,下同)和src目錄中(參考以上目錄結構)。我們先給出兩個CMakeLists.txt的內容,在下一節中再對兩個CMakeLists.txt進行詳細介紹。兩個CMakeLists.txt檔案的內容分別如下:
2.1 根目錄中CMakeLists內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cmake_minimum_required (VERSION 2.6)
 
project (CRNode)
 
ADD_SUBDIRECTORY(src bin)
 
#SET(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR})
SET(CMAKE_INSTALL_PREFIX /usr/local)
 
INSTALL(PROGRAMS crnode.sh DESTINATION bin)
 
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/crnode)
 
INSTALL(DIRECTORY doc/ DESTINATION share/doc/crnode)

2.2 src/CMakeLists.txt內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
INCLUDE_DIRECTORIES(/usr/include/thrift)
 
SET(SRC_LIST main.cc
        rpc/CRMasterCaller.cpp
        rpc/CRNode_server.skeleton.cpp
        rpc/Schd_constants.cpp
        rpc/CRMaster.cpp
        rpc/CRNode.cpp
        rpc/Schd_types.cpp
        task/TaskExecutor.cpp
        task/TaskMoniter.cpp
        util/Const.cpp
        util/Globals.cc
        util/utils.cc
        util/Properties.cpp
        )
 
ADD_EXECUTABLE(crnode ${SRC_LIST})
 
TARGET_LINK_LIBRARIES(crnode log4cpp thrift)
 
INSTALL(TARGETS crnode
        RUNTIME DESTINATION bin
)

3. CMake語法
A. 變數使用${}方式取值,但是在 IF 控制語句中是直接使用變數名;
B. 指令(引數 1 引數 2…),引數使用括弧括起,引數之間使用空格或分號分開;
C. 指令是大小寫無關的,引數和變數是大小寫相關的。但,推薦你全部使用大寫指令。

4. CMakeLists.txt剖析
4.1 cmake_minimum_required命令

1
cmake_minimum_required (VERSION 2.6)

    規定cmake程式的最低版本。這行命令是可選的,我們可以不寫這句話,但在有些情況下,如果CMakeLists.txt檔案中使用了一些高版本cmake特有的一些命令的時候,就需要加上這樣一行,提醒使用者升級到該版本之後再執行cmake。

4.2 project命令

3
project (CRNode)

    指定專案的名稱。專案最終編譯生成的可執行檔案並不一定是這個專案名稱,而是由另一條命令確定的,稍候我們再介紹。
    但是這個專案名稱還是必要的,在cmake中有兩個預定義變數:< projectname >_BINARY_DIR以及< projectname >_SOURCE_DIR,在我們的專案中,兩個變數分別為:CRNode_BINARY_DIR和CRNode_SOURCE_DIR。內部編譯情況下兩者相同,後面我們會講到外部編譯,兩者所指代的內容會有所不同。要理解這兩個變數的定義,我們首先需要了解什麼是“外部構建(out-of-source build)”,我們將在下一小節中介紹“外部構建”。
同時cmake還預定義了PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR變數。在我們的專案中,PROJECT_BINARY_DIR等同於CRNode_BINARY_DIR,PROJECT_SOURCE_DIR等同於CRNode_SOURCE_DIR。在實際的應用用,我強烈推薦使用PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR變數,這樣即使專案名稱發生變化也不會影響CMakeLists.txt檔案。

4.3 外部構建
    假設我們此時已經完成了兩個CMakeLists.txt檔案的編寫,可以執行cmake命令生成Makefile檔案了。此時我們由兩種方法可以執行cmake、編譯和安裝:

1
2
cmake .
make

或者

1
2
3
4
mkdir build
cd build
cmake ..
make

    兩種方法最大的不同在於執行cmake和make的工作路徑不同。第一種方法中,cmake生成的所有中間檔案和可執行檔案都會存放在專案目錄中;而第二種方法中,中間檔案和可執行檔案都將存放再build目錄中。第二種方法的優點顯而易見,它最大限度的保持了程式碼目錄的整潔。同時由於第二種方法的生成、編譯和安裝是發生在不同於專案目錄的其他目錄中,所以第二種方法就叫做“外部構建”。
    回到之前的疑問,再外部構建的情況下,PROJECT_SOURCE_DIR指向的目錄同內部構建相同,仍然為~/workspace/CRNode,而PROJECT_BINARY_DIR則有所不同,指向~/workspace/CRNode/build目錄。
    當然,cmake強烈推薦使用外部構建的方法。

4.4 ADD_SUBDIRECTORY命令

5
ADD_SUBDIRECTORY(src bin)

    ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])這個指令用於向當前工程新增存放原始檔的子目錄,並可以指定中間二進位制和目標二進位制存放的位置。EXCLUDE_FROM_ALL 引數的含義是將這個目錄從編譯過程中排除。比如,工程的 example,可能就需要工程構建完成後,再進入 example 目錄單獨進行構建。
    在我們的專案中,我們添加了src目錄到專案中,而把對應於src目錄生成的中間檔案和目標檔案存放到bin目錄下,在上一節舉例中“外部構建”的情況下,中間檔案和目標檔案將存放在build/srcobj目錄下。

4.5 SET命令

8
SET(CMAKE_INSTALL_PREFIX /usr/local)

    現階段,只需要瞭解SET命令可以用來顯式的定義變數即可。在以上的例子中,我們顯式的將CMAKE_INSTALL_PREFIX的值定義為/usr/local,如此在外部構建情況下執行make install命令時,make會將生成的可執行檔案拷貝到/usr/local/bin目錄下。
    當然,可執行檔案的安裝路徑CMAKE_INSTALL_PREFIX也可以在執行cmake命令的時候指定,cmake引數如下:

cmake -DCMAKE_INSTALL_PREFIX=/usr ..

    如果cmake引數和CMakeLists.txt檔案中都不指定該值的話,則該值為預設的/usr/local。

4.6 INCLUDE_DIRECTORIES命令

1
INCLUDE_DIRECTORIES(/usr/include/thrift)

    INCLUDE_DIRECTORIES類似gcc中的編譯引數“-I”,指定編譯過程中編譯器搜尋標頭檔案的路徑。當專案需要的標頭檔案不在系統預設的搜尋路徑時,需要指定該路徑。在我們的專案中,log4cpp所需的標頭檔案都存放在/usr/include下,不需要指定;但thrift的標頭檔案沒有存放在系統路徑下,需要指定搜尋其路徑。

4.7 ADD_EXECUTABLE和ADD_LIBRARY

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SET(SRC_LIST main.cc
        rpc/CRMasterCaller.cpp 
        rpc/CRNode_server.skeleton.cpp 
        rpc/Schd_constants.cpp 
        rpc/CRMaster.cpp 
        rpc/CRNode.cpp 
        rpc/Schd_types.cpp 
        task/TaskExecutor.cpp
        task/TaskMoniter.cpp
        util/Const.cpp 
        util/Globals.cc
        util/utils.cc
        util/Properties.cpp
        )
 
ADD_EXECUTABLE(CRNode ${SRC_LIST})

    ADD_EXECUTABLE定義了這個工程會生成一個檔名為 CRNode 的可執行檔案,相關的原始檔是 SRC_LIST 中定義的原始檔列表。需要注意的是,這裡的CRNode和之前的專案名稱沒有任何關係,可以任意定義。

4.8 EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH
    我們可以通過 SET 指令重新定義 EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH 變數來指定最終的目標二進位制的位置(指最終生成的CRNode可執行檔案或者最終的共享庫,而不包含編譯生成的中間檔案)。
    命令如下:

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

    需要注意的是,在哪裡 ADD_EXECUTABLE 或 ADD_LIBRARY,如果需要改變目標存放路徑,就在哪裡加入上述的定義。

4.9 TARGET_LINK_LIBRARIES命令

20
TARGET_LINK_LIBRARIES(CRNode log4cpp thrift)

    這句話指定在連結目標檔案的時候需要連結的外部庫,其效果類似gcc的編譯引數“-l”,可以解決外部庫的依賴問題。

4.10 INSTALL命令
    在執行INSTALL命令的時候需要注意CMAKE_INSTALL_PREFIX引數的值。該引數在3.5中已經有所介紹。其命令形式如下:

INSTALL(TARGETS targets...
	[[ARCHIVE|LIBRARY|RUNTIME]
	[DESTINATION < dir >]
	[PERMISSIONS permissions...]
	[CONFIGURATIONS
	[Debug|Release|...]]
	[COMPONENT < component >]
	[OPTIONAL]
	] [...])

    引數中的 TARGETS 後面跟的就是我們通過 ADD_EXECUTABLE 或者 ADD_LIBRARY 定義的目標檔案,可能是可執行二進位制、動態庫、靜態庫。
    DESTINATION 定義了安裝的路徑,如果路徑以/開頭,那麼指的是絕對路徑,這時候CMAKE_INSTALL_PREFIX 其實就無效了。如果你希望使用 CMAKE_INSTALL_PREFIX 來定義安裝路徑,就要寫成相對路徑,即不要以/開頭,那麼安裝後的路徑就是${CMAKE_INSTALL_PREFIX} /< destination 定義的路徑>
    你不需要關心 TARGETS 具體生成的路徑,只需要寫上 TARGETS 名稱就可以了。
    非目標檔案的可執行程式安裝(比如指令碼之類):

INSTALL(PROGRAMS files... DESTINATION < dir >
	[PERMISSIONS permissions...]
	[CONFIGURATIONS [Debug|Release|...]]
	[COMPONENT < component >]
	[RENAME < name >] [OPTIONAL])

    跟上面的 FILES 指令使用方法一樣,唯一的不同是安裝後許可權為OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 許可權目錄的安裝。
    安裝一個目錄的命令如下:

INSTALL(DIRECTORY dirs... DESTINATION < dir >
	[FILE_PERMISSIONS permissions...]
	[DIRECTORY_PERMISSIONS permissions...]
	[USE_SOURCE_PERMISSIONS]
	[CONFIGURATIONS [Debug|Release|...]]
	[COMPONENT < component >]
	[[PATTERN < pattern > | REGEX < regex >]
	[EXCLUDE] [PERMISSIONS permissions...]] [...])

    DIRECTORY 後面連線的是所在 Source 目錄的相對路徑,但務必注意:abc 和 abc/有很大的區別。如果目錄名不以/結尾,那麼這個目錄將被安裝為目標路徑下的 abc,如果目錄名以/結尾,代表將這個目錄中的內容安裝到目標路徑,但不包括這個目錄本身。我們來看一個例子:

1
2
3
4
5
INSTALL(DIRECTORY icons scripts/ DESTINATION share/myproj
	PATTERN "CVS" EXCLUDE
	PATTERN "scripts/*"
	PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
	GROUP_EXECUTE GROUP_READ)

    這條指令的執行結果是:
    將 icons 目錄安裝到 < prefix >/share/myproj,將 scripts/中的內容安裝到< prefix >/share/myproj,不包含目錄名為 CVS 的目錄,對於 scripts/*檔案指定許可權為 OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ。
    因為crnode.txt 要安裝到/< prefix >/share/doc/crnode,所以我們不能直接安裝整個 doc 目錄,這裡採用的方式是安裝 doc 目錄中的內容,也就是使用”doc/”在工程檔案中新增:

1
INSTALL(DIRECTORY doc/ DESTINATION share/doc/crnode)

5. 編譯安裝
    編譯安裝結果如下:

  1. [[email protected] build]# cmake ..  
  2. -- Configuring done  
  3. -- Generating done  
  4. -- Build files have been written to: /home/fify/workspace/CRNode/build  
  5. [[email protected] build]# make  
  6. Scanning dependencies of target crnode  
  7. [  7%] Building CXX object srcobj/CMakeFiles/crnode.dir/main.cc.o  
  8. [ 15%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRMasterCaller.cpp.o  
  9. [ 23%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRNode_server.skeleton.cpp.o  
  10. [ 30%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/Schd_constants.cpp.o  
  11. [ 38%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRMaster.cpp.o  
  12. [ 46%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRNode.cpp.o  
  13. [ 53%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/Schd_types.cpp.o  
  14. [ 61%] Building CXX object srcobj/CMakeFiles/crnode.dir/task/TaskExecutor.cpp.o  
  15. [ 69%] Building CXX object srcobj/CMakeFiles/crnode.dir/task/TaskMoniter.cpp.o  
  16. [ 76%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Const.cpp.o  
  17. [ 84%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Globals.cc.o  
  18. [ 92%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/utils.cc.o  
  19. [100%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Properties.cpp.o  
  20. Linking CXX executable crnode  
  21. [[email protected] build]# make install  
  22. [100%] Built target crnode  
  23. Install the project...  
  24. -- Install configuration: ""  
  25. -- Installing: /usr/local/bin/crnode.sh  
  26. -- Installing: /usr/local/share/doc/crnode/COPYRIGHT  
  27. -- Installing: /usr/local/share/doc/crnode/README  
  28. -- Installing: /usr/local/share/doc/crnode  
  29. -- Installing: /usr/local/share/doc/crnode/crnode.txt  
  30. -- Installing: /usr/local/bin/crnode  

    大功告成!更多內容請參考《CMake Practice》,再次對《CMake Practice》的作者表示感謝!

相關推薦

CMake快速入門教程實戰

轉自http://blog.csdn.net/ljt20061908/article/details/11736713 0. 前言     一個多月前,由於工程專案的需要,匆匆的學習了一下cmake的使用方法,現在有時間拿出來整理一下。本文假設你已經學會了cmake的使用方法,如果你還不會使用cmake,

Systemd入門教程實戰篇(轉)

現在 重啟 penssh span 日誌 才會 查看 筆記本 dep 作者: 阮一峰 日期: 2016年3月 8日 上一篇文章,我介紹了 Systemd 的主要命令,今天介紹如何使用它完成一些基本的任務。 一、開機啟動 對於那些支持 Systemd 的軟

ubuntu快速入門教程初次見面

切換 優化 第三方軟件 技術分享 計算 shu 做的 基本 移動設備 1 什麽是ubuntu? Ubuntu(友幫拓、優般圖、烏班圖)是一個以桌面應用為主的開源GNU/Linux操作系統,Ubuntu 是基於Debian GNU/Linux,支持x86、amd64(即x6

hadoop快速入門教程hadoop安裝包下載與監控參數說明

分布式 height tex region 集群 RoCE 發行版 store serve 前階段用了差不多兩周的時間把DKhadoop的運行環境搭建以及安裝的各個操作都介紹了一遍。關於DKhadoop安裝包下載也只是順帶說了一下,但好像大快搜索的服務器在更新,新的下載頁面

CentOS_7 Systemd 入門教程實戰

一、開機啟動 對於那些支援 Systemd 的軟體,安裝的時候,會自動在/usr/lib/systemd/system目錄新增一個配置檔案。 如果你想讓該軟體開機啟動,就執行下面的命令(以httpd.service為例)。 $ sudo systemctl enable

DbForge Data Compare for SQL Server入門教程連線到資料庫、快速同步兩個資料庫

在連線到資料庫之前,必須建立伺服器連線。 要建立連線: 1. 在資料庫選單上,單擊新建連線。將開啟“ 資料庫連線屬性” 對話方塊。 2. 在“ 伺服器” 組合框中,單擊“ <瀏覽...>” 。將開啟“ 瀏覽伺服器” 視窗。 3. 在“ 本地伺服器” 選

無廢話MVC入門教程九[實戰使用者註冊與登陸]

MVC入門系列教程-視訊版本,已入駐51CTO學院,文字+視訊學效果更好哦。視訊連結地址如下: 點我檢視視訊。另外,針對該系列教程博主提供有償技術支援,群號:226090960,群內會針對該教程的問題進行及時解答,公用性問題統一講解。學習.NET MVC 只看在《無廢話系列》足夠了,《無廢話系列》簡單、快速、

無廢話MVC入門教程十[實戰使用者管理]

MVC入門系列教程-視訊版本,已入駐51CTO學院,文字+視訊學效果更好哦。視訊連結地址如下: 點我檢視視訊。另外,針對該系列教程博主提供有償技術支援,群號:226090960,群內會針對該教程的問題進行及時解答,公用性問題統一講解。學習.NET MVC 只看在《無廢話系列》足夠了,《無廢話系列》簡單、快速、

Numpy快速入門教程(三)SciPy,Matplotlib

首先宣告本篇部落格是本人學習CS231n的學習筆記,分享給大家當作參考。 SciPy Numpy提供了高效能的多維陣列,以及計算和運算元組的基本工具。SciPy基於Numpy,提供了大量的計算和運算元組的函式,這些函式對於不同型別的科學和工程計算非常有用。

Linux Capabilities 入門教程基礎實戰

該系列文章總共分為三篇: Linux Capabilities 入門教程:概念篇 Linux Capabilities 入門教程:基礎實戰篇 待續... 上篇文章介紹了 Linux capabilities 的誕生背景和基本原理,本文將會通過具體的示例來展示如何檢視和設定檔案的 capabilities。

Linux Capabilities 入門教程進階實戰

> 原文連結:[https://fuckcloudnative.io/posts/linux-capabilities-in-practice-2/](https://fuckcloudnative.io/posts/linux-capabilities-in-practice-2/) 該系列文章總共分為三

Django REST framework 的快速入門教程

ret turn ads 使用 blog 所有 定義 想去 cti CRM-API項目搭建 序列器(Serializers) 首先,我們來定義一些序列器。我們來創建一個新的模塊(module)叫做 crm/rest_searializer.py ,這是我們用來描述數據是如何

ThinkPHP3.1快速入門教程

pan html manual thinkphp 教程 font 入門教程 入門 href ThinkPHP3.1快速入門教程 http://www.thinkphp.cn/info/155.html -----------------------

AndroidStudio快速入門打造你的開發工具,settings必備

ack src paste libs box 下載 解釋 繼續 odi http://blog.csdn.net/jf_1994/article/details/50085825 前言:這裏是使用AS的基本設置,適合新入手的朋友閱讀,將這裏介紹的設置完基本使用無憂啦。 1、

AngularJS [ 快速入門教程 ]

空數組 spa put bold [ ] 地址 替換 個人 傳遞 前 序 S N AngularJS是什麽? 我想既然大家查找AngularJS就證明大家多多少少對AngularJS都會有了解。 AngularJS就是,使用JavaScript編寫的客戶端

Systemd入門教程命令篇(轉)

apache 完整 start -o 一是 analyze sudo one iso 作者: 阮一峰 日期: 2016年3月 7日 Systemd 是 Linux 系統工具,用來啟動守護進程,已成為大多數發行版的標準配置。 本文介紹它的基本用法,分

小程序開發快速入門教程(附源碼)

五分鐘上手-微信小程序 1:用沒有註冊過微信公眾平臺的郵箱註冊一個微信公眾號, 申請帳號 ,點擊 https://mp.weixin.qq.com/wxopen/waregister?action=step1 根據指引填寫信息和提交相應的資料,就可以擁有自己的小程序帳號。註冊完成之後開始登

Linux快速入門教程-進程管理ipcs命令學習

Linux Linux入門 Linux運維 Linux命令 使用Linux系統必備的技能之一就是Linux進程管理,系統運行的過程正是無數進程在運行的過程。這些進程的運行需要占用系統的內存等資源,做好系統進程的管理,對於我們合理分配、使用系統資源有非常大的意義。今天我們來看進程管理命令中的ip

HTML5入門教程 Cookie會話跟蹤技術~

會話跟蹤 嵌入 網絡 影響 自動 img 更改 txt文件 發送 1. Cookie會話跟蹤技術介紹 會話跟蹤是Web程序中常用的技術,用來跟蹤用戶的整個會話。常用的會話跟蹤技術是Cookie與Session。Cookie通過在客戶端記錄信息確定用戶身份,可以在客戶端保存臨

GNU開發工具——CMake快速入門

CMake 快速入門GNU開發工具——CMake快速入門 一、CMake簡介 不同Make工具,如GNU Make、QT的qmake、微軟的MS nmake、BSD Make(pmake)等,遵循著不同的規範和標準,所執行的Makefile格式也不同。如果軟件想跨平臺,必須要保證能夠在不同平臺編譯。而如果使用