無論生活還是工作上,做過的事,需要總結下。
接觸cmake,一般都會看一本書 <<cmake 實踐>>. 這是cmake的入門書。我就不多說了。
下面說一下我對部分cmake指令的使用與了解,不正确的,請大家指點,謝謝!
1. 所有的注釋,都以#開頭。
#XXX Build Script
#CMakeLists.txt
#
#Copyright (c) 2011, L
#All rights reserved.
2. cmake版本的控制。
cmake_minimum_required (VERSION 2.8)
3. 定義項目名稱。
PROJECT (xxx)
4. 如果想看到更多cmake編譯時候的資訊,置為ON,否則為OFF.
set(CMAKE_VERBOSE_MAKEFILE ON)
5. 在項目中,我們一般會用到一些第三方庫。cmake支援一些,注意,隻是部分。例如對Boost的支援,對apr的不支援。
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREAD ON)
find_package(Boost 1.4.3 REQUIRED)
如果你的機器上裝有Boost,它會自動找出來,找不出來,就會報錯,停止編譯。(REQUIRED的作用)
在項目中,我們用到了apache runtime library(apr).cmake不支援,我的解決方法手動添加apr的路徑。
例如:
#apr
SET(APR_ROOT $ENV{APR_DIST})
嘗試寫個.cmkae子產品,用findXXX調用,但是不知道該如何如找apr的安裝路徑。有知道的朋友,希望指點,謝謝!
找到Boost後,我們會自動得到它的include路徑和lib路徑。
同時,我們可以得到一些庫的名稱。
MESSAGE(STATUS "Boost include path:" ${Boost_INCLUDE_DIRS})
MESSAGE(STATUS "Boost lib path:" ${Boost_LIBRARY_DIRS})
FIND_PACKAGE(Boost REQUIRED COMPONENTS system)
STRING(REPLACE "boost_system" "boost_regex" Boost_REGEX_LIBRARY ${Boost_SYSTEM_LIBRARY})
STRING(REPLACE "boost_system" "boost_regex" Boost_REGEX_LIBRARY_DEBUG ${Boost_SYSTEM_LIBRARY_DEBUG})
STRING(REPLACE "boost_system" "boost_regex" Boost_REGEX_LIBRARY_RELEASE ${Boost_SYSTEM_LIBRARY_RELEASE})
6. 如果你的cmake實作中,用到了一些子產品,例如*.cmake.這個時候,需要
#set module path. for FindXXX.cmake
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
7. 建立宏。
例如你建的工程是unicode 編碼,可以這樣:
#set character set. unicode
add_definitions(-DUNICODE -D_UNICODE)
8. 添加子目錄,它會去子目錄中尋找CmakeLists.txt,然後執行它。
ADD_SUBDIRECTORY(subdir)
9. 将一個檔案下的編譯用的源檔案添加到一個宏清單中。
AUX_SOURCE_DIRECTORY(. SRC_LIST)
注意,它隻是将.cc .cpp .c的檔案添加到SRC_LIST中,.h除外。
10. 如果你想将.h檔案也加進來,使用
file (GLOB HEADERS "include/*.h")
SET(SRC_LIST ${SRC_LIST} ${HEADERS})
注意GLOB這個參數,它不支援子目錄。如果你想讓它支援子目錄,用GLOB_RECURSE。
在vs中可以建立子檔案夾,這樣會使我們的項目看上去美觀,規範。
cmake支援這一功能。
source_group(Include\\utils FILES ${HEADERS})
這個可以親自試試,看看效果。在使用這個指令的時候,本想用regex,正則來處理,試過了好幾次,發現cmake好像不怎麼支援正則,例如Perl的文法。
例如:if(${f} MATCHES "(.*)(\.h)$")
如在這塊有心得的朋友,希望指點下,哈哈。
11. 頭檔案包含路徑及庫路徑
INCLUDE_DIRECTORIES
link_directories
12. 在windows+vs中,如果我們想改變項目的輸出路徑,dll, .lib,需要
IF(MSVC)
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/lib )
ELSE(MSVC)
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib )
ENDIF(MSVC)
13. 檢查一個檔案或目錄是否存在,用
if(NOT EXISTS ${APR_ROOT})
endif()
注意這裡的if,是小寫的,用大寫的,就會報錯,為此,我折騰了半天。
14. cmake提供了gui界面。如果想使用界面方式,例如:設定變量MY_ROOT的值
SET(MY_ROOT "/usr/lib" CACHE PATH "my root path")
記得不要加FORCE。加上了,會rebuild,不是我們想要的效果。
好了,希望對用得到的朋友,有所幫助。謝謝!