在實際復雜的項目之中,會有很多的源文件,以及對於庫的依賴,如果直接使用makefile會比較的繁瑣,而且makefile的推導規則也非常多,對多目錄的支持也比較復雜。
最近看了一下cmake,發現配置起來比直接使用makefile要方便很多,學習成本也比較低。
現在假設我們有一個server目錄,內部有一個redis目錄,就用兩個目錄來說明問題。
在server目錄下,我們創建一個CMakeLists.txt,在redis下也創建一個同樣名字的文件,但是內容不同。
由於只昨天晚上學習了一下cmake的使用,粗淺的將實際項目中的makefile替換了,有些不對的地方如果后續發現了,將進行改正
1、首先看下server目錄下的CMakeLists.txt
PROJECT(server)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
INCLUDE_DIRECTORIES("/usr/local/include")
INCLUDE_DIRECTORIES("/usr/include/mysql")
INCLUDE_DIRECTORIES("/usr/include/boost")
INCLUDE_DIRECTORIES("/usr/include/")
ADD_SUBDIRECTORY(redis)
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
MESSAGE(STATUS "dir src:" +${DIR_SRCS})
#ADD_EXECUTABLE(server${DIR_SRCS})
LINK_DIRECTORIES("/usr/local/lib")
LINK_DIRECTORIES("/usr/local/mysql/lib")
LINK_DIRECTORIES("/usr/local/protobuf/lib")
#LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu/")
ADD_EXECUTABLE(server ${DIR_SRCS})
TARGET_LINK_LIBRARIES(server redis)
TARGET_LINK_LIBRARIES(server net)
TARGET_LINK_LIBRARIES(server log4cplus)
TARGET_LINK_LIBRARIES(server mysqlclient)
TARGET_LINK_LIBRARIES(server boost_system)
TARGET_LINK_LIBRARIES(server boost_thread)
TARGET_LINK_LIBRARIES(server protobuf)
#TARGET_LINK_LIBRARIES(server net)
TARGET_LINK_LIBRARIES(server TinyXml)
需要對使用到的關鍵字逐一進行一下說明:
(1) PROJECT 指定我們項目的名字,跟最后生成的可執行文件名是可以不一樣的,兩者沒有什么關系
(2) CMAKE_MINIMUM_REQUIRED 指定cmake的版本,我用的環境是Ubuntu14 和 cmake2.8,如果不指定的話,在2.8下會直接提示錯誤的
(3) INCLUDE_DIRECTORIES 指定項目使用到的頭文件目錄,可以一次包含多個頭文件目錄,我為了清晰,每次只包含一個。
(4) ADD_SUBDIRECTORY 這個就是指定我們用到的子目錄,在這里就是redis
(5) AUX_SOURCE_DIRECTORY 這個是指定我們server目錄下需要用到的所有問題,這里使用一個"."當前目錄符號替代就可以了,但是在子目錄下如果這么這么使用就會報錯,目前還不太清楚為什么。
(6) MESSAGE 屬於提示信息,方便查看的,可有可無
(7) LINK_DIRECTORIES 指定程序需要鏈接的庫目錄
(8) ADD_EXECUTABLE 指定我們程序最后可執行文件的名字
(9) TARGET_LINK_LIBRARIES 最后是鏈接時候用到的庫文件名字,跟INCLUDE_DIRECTORIES,也可以一次寫多個,這里需要特別注意的是,其中net庫是自己編寫的,其中用到了boost_thread庫,如果將net庫寫在boost_thread庫后面的話,在鏈接的時候,會提示找不到boost_thread庫,一定要寫在net庫依賴庫的前面
具體的每個關鍵字的用法,可以網上找下cmake的手冊看下
2、我們看下redis子目錄下的CMakeLists.txt寫法
#AUX_SOURCE_DIRECTORY(. DIR_REDIS_SRCS)
SET(DIR_REDIS_SRCS
anet.cpp
)
MESSAGE(STATUS ${DIR_REDIS_SRCS})
ADD_LIBRARY (redis ${DIR_REDIS_SRCS})
注意將redis子目錄編譯成了一個lib庫,然后跟server目錄下進行連接了
3、然后就是開始使用cmake進行編譯了,在server目錄下使用“cmake .” 命令進行預生成,cmake會檢查語法以及編譯環境,如果沒問題,就可以使用make指令進行實際的編譯操作了