CMake編譯原理
CMake是一種跨平臺編譯工具,比make更為高階,使用起來要方便得多。CMake主要是編寫CMakeLists.txt檔案,然後用cmake命令將CMakeLists.txt檔案轉化為make所需要的makefile檔案,最後用make命令編譯原始碼生成可執行程式或共享庫(so(shared object))。因此CMake的編譯基本就兩個步驟:
- cmake
- make
compile.sh
g++ -rdynamic ../include/incl/tfc_base_config_file.cpp ../include/mq/*.cpp local_util.cpp AgentMemRpt.cpp AgentDiskRpt.cpp AgentLoadRpt.cpp AgentIoRpt.cpp AgentNetRpt.cpp AgentCpuRpt.cpp AgentProcessRpt.cpp AgentParentRpt.cpp AgentSysTop_5.cpp BaseFeatureRptMain.cpp -o rpt_main -I../include/incl -I../include/mq -I../include/rapidjson -lpthread -ldl
複製程式碼
CMake說明
一般把CMakeLists.txt檔案放在工程目錄下,使用時,先建立一個叫build的資料夾(這個並非必須,因為cmake命令指向CMakeLists.txt所在的目錄,例如cmake .. 表示CMakeLists.txt在當前目錄的上一級目錄。cmake後會生成很多編譯的中間檔案以及makefile檔案,所以一般建議新建一個新的目錄,專門用來編譯),然後執行下列操作:
cd build
cmake ..
make
複製程式碼
其中cmake .. 在build裡生成Makefile,make根據生成makefile檔案,編譯程式,make應當在有Makefile的目錄下,根據Makefile生成可執行檔案。
編寫 CMakeList.txt
# 1. 宣告要求的cmake最低版本
cmake_minimum_required( VERSION 2.8 )
# 2. 新增c++11標準支援
#set( CMAKE_CXX_FLAGS "-std=c++11" )
# 3. 宣告一個cmake工程
PROJECT(rpt_main)
MESSAGE(STATUS "Project: SERVER") #列印相關訊息訊息
# 4. 標頭檔案
include_directories(
${PROJECT_SOURCE_DIR}/../include/mq
${PROJECT_SOURCE_DIR}/../include/incl
${PROJECT_SOURCE_DIR}/../include/rapidjson
)
# 5. 通過設定SRC變數,將原始碼路徑都給SRC,如果有多個,可以直接在後面繼續新增
set(SRC
${PROJECT_SOURCE_DIR}/../include/incl/tfc_base_config_file.cpp
${PROJECT_SOURCE_DIR}/../include/mq/tfc_ipc_sv.cpp
${PROJECT_SOURCE_DIR}/../include/mq/tfc_net_ipc_mq.cpp
${PROJECT_SOURCE_DIR}/../include/mq/tfc_net_open_mq.cpp
${PROJECT_SOURCE_DIR}/local_util.cpp
${PROJECT_SOURCE_DIR}/AgentMemRpt.cpp
${PROJECT_SOURCE_DIR}/AgentDiskRpt.cpp
${PROJECT_SOURCE_DIR}/AgentLoadRpt.cpp
${PROJECT_SOURCE_DIR}/AgentIoRpt.cpp
${PROJECT_SOURCE_DIR}/AgentNetRpt.cpp
${PROJECT_SOURCE_DIR}/AgentCpuRpt.cpp
${PROJECT_SOURCE_DIR}/AgentProcessRpt.cpp
${PROJECT_SOURCE_DIR}/AgentParentRpt.cpp
${PROJECT_SOURCE_DIR}/AgentSysTop_5.cpp
${PROJECT_SOURCE_DIR}/BaseFeatureRptMain.cpp
)
# 6. 建立共享庫/靜態庫
# 設定路徑(下面生成共享庫的路徑)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
# 即生成的共享庫在工程資料夾下的lib資料夾中
set(LIB_NAME rpt_main_lib)
# 建立共享庫(把工程內的cpp檔案都建立成共享庫檔案,方便通過標頭檔案來呼叫)
# 這時候只需要cpp,不需要有主函式
# ${PROJECT_NAME}是生成的庫名 表示生成的共享庫檔案就叫做 lib工程名.so
# 也可以專門寫cmakelists來編譯一個沒有主函式的程式來生成共享庫,供其它程式使用
# SHARED為生成動態庫,STATIC為生成靜態庫
add_library(${LIB_NAME} STATIC ${SRC})
# 7. 連結庫檔案
# 把剛剛生成的${LIB_NAME}庫和所需的其它庫連結起來
# 如果需要連結其他的動態庫,-l後接去除lib字首和.so字尾的名稱,以連結
# libpthread.so 為例,-lpthread
target_link_libraries(${LIB_NAME} pthread dl)
# 8. 編譯主函式,生成可執行檔案
# 先設定路徑
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
# 可執行檔案生成
add_executable(${PROJECT_NAME} ${SRC})
# 這個可執行檔案所需的庫(一般就是剛剛生成的工程的庫咯)
target_link_libraries(${PROJECT_NAME} pthread dl ${LIB_NAME})
複製程式碼
使用 cmake
- 進入
/home/pzqu/agent/libvirt_base_feature/build
目錄 - 執行命令
cmake ..
- 檢視生成的目錄結構,此目錄結構是中間程式碼,不用提交到git
[root@TJSJZVM000456 /home/pzqu/agent/libvirt_base_feature/build]# tree
.
|-- CMakeCache.txt
|-- CMakeFiles
| |-- 2.8.12.2
| | |-- CMakeCCompiler.cmake
| | |-- CMakeCXXCompiler.cmake
| | |-- CMakeDetermineCompilerABI_C.bin
| | |-- CMakeDetermineCompilerABI_CXX.bin
| | |-- CMakeSystem.cmake
| | |-- CompilerIdC
| | | |-- CMakeCCompilerId.c
| | | `-- a.out
| | `-- CompilerIdCXX
| | |-- CMakeCXXCompilerId.cpp
| | `-- a.out
| |-- CMakeDirectoryInformation.cmake
| |-- CMakeOutput.log
| |-- CMakeTmp
| |-- Makefile.cmake
| |-- Makefile2
| |-- TargetDirectories.txt
| |-- cmake.check_cache
| |-- progress.marks
| |-- rpt_main.dir
| | |-- DependInfo.cmake
| | |-- build.make
| | |-- cmake_clean.cmake
| | |-- depend.make
| | |-- flags.make
| | |-- home
| | | `-- pzqu
| | | `-- agent
| | | `-- include
| | | |-- incl
| | | `-- mq
| | |-- link.txt
| | `-- progress.make
| `-- rpt_main_lib.dir
| |-- DependInfo.cmake
| |-- build.make
| |-- cmake_clean.cmake
| |-- cmake_clean_target.cmake
| |-- depend.make
| |-- flags.make
| |-- home
| | `-- pzqu
| | `-- agent
| | `-- include
| | |-- incl
| | `-- mq
| |-- link.txt
| `-- progress.make
|-- Makefile
`-- cmake_install.cmake
複製程式碼
- 使用make命令編譯得到二進位制檔案
- 二進位制檔案所在目錄(CMakeLists.txt檔案配置)
下次教大家如何用Clion自動同步程式碼到伺服器上,並進行debug