使用cmake編譯Ceph簡易教程
ceph大概從jewel版開始使用cmake進行ceph專案的編譯管理。
但是基本網上沒有關於ceph cmake的使用介紹,對於小白我來說,因為對cmake還有以前的autoconfig不瞭解,甚至對Makefile的編寫規則都不太懂,只懂得用簡單的gcc/g++命令進行編譯。但是在修改/除錯ceph程式碼時,由於src程式碼目錄結構眾多,庫檔案的引用關聯太多,使用gcc基本上很難編譯成功。
經過一段時間的Makefile和cmkae命令的學習摸索,基本上了解如何用cmake編譯ceph了。謹寫此文備忘,並分享給其它小白。
Makefile
這裡有篇很詳盡的Makefile規則教程:Linux Makefile詳細教程
關於Makefile的編寫規則不在本文章介紹範圍內,Makefile的介紹網上一搜一大堆,請自行百度/google。
在剛開始學習C/C++的時候,還記得使用的是visual-6.0。確實很方便,寫完程式後點擊一下執行就能自動跑起來。雖然使用IDE工具可以讓新手暫時省略各種編譯連結過程,將注意力集中在程式語言本身。但是長久以往,就會離不開IDE。一旦沒有了IDE環境,就感覺不會寫程式碼一般,特別是從Windows平臺切換到Linux平臺時,感受特別深刻。
在Linux中,簡單的程式可以使用gcc編譯器直接進行編譯,但是對於大專案來說,Makefile就是主要的編譯管理工具。Makefile的主要作用是告訴make命令如何對專案程式進行編譯連結,並生成可執行檔案的過程。
原則上,編寫完Makefile後,在shell上執行make命令後,就會自動在本目錄下查詢Makefile檔案並進行編譯連結。
cmake
這裡有篇很簡單的cmake入門部落格:如何編寫CMakeList.txt
cmake同樣地網上介紹一大堆,希望瞭解的自行百度/google
cmake是跨平臺的編譯管理工具。主要作用其實就是根據規則自動生成Makefile,然後使用make命令進行編譯連結。所以使用cmake需要如下步驟:
1. 編寫CMakeList.txt檔案
2. 生成Makefile,mkdir build && cd build && cmake ../CMakeList.txt。因為cmake生成的目錄檔案很多,一般情況下都會建立一個build目錄進行放置。
3. 執行make 命令進行專案編譯連結。
cmake具體上比automake、autoconfig還有其它編譯管理工具在具體上有什麼優勢,因為我之前沒使用過autoconfig或者automake,所以不太懂。只知道cmake在跨平臺、大工程上的管理優勢明顯。但是cmake定義為高階編譯配置工具,功能豐富、相容性好、操作簡單,知道這些感覺就夠了。同時通過ceph編譯的使用體驗上來說,cmake還是比autoconfig簡單多多了。
cmake生成的目錄結果大致如下所示:
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.2.2
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── a.out
│ │ │ │ └── CMakeCCompilerId.c
│ │ │ └── CompilerIdCXX
│ │ │ ├── a.out
│ │ │ └── CMakeCXXCompilerId.cpp
│ │ ├── cmake.check_cache
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── CMakeTmp
│ │ ├── feature_tests.bin
│ │ ├── feature_tests.c
│ │ ├── feature_tests.cxx
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── progress.marks
│ │ ├── TargetDirectories.txt
│ │ └── test_sqrt.dir
│ │ ├── build.make
│ │ ├── C.includecache
│ │ ├── cmake_clean.cmake
│ │ ├── DependInfo.cmake
│ │ ├── depend.internal
│ │ ├── depend.make
│ │ ├── flags.make
│ │ ├── link.txt
│ │ ├── progress.make
│ │ └── src
│ │ ├── b.c.o
│ │ └── main.c.o
│ ├── cmake_install.cmake
│ ├── Makefile
│ └── test_sqrt
├── CMakeLists.txt
├── include
│ └── b.h
└── src
├── b.c
└── main.c123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
使用cmake編譯ceph
終於到正題了。之前學習ceph的時候,想修改程式碼,比如增加些列印語句等等,這還好辦,直接從新make對應的模組就好了。比如修改了rbd模組相關檔案,那就執行make rbd就行。但是如果想添加個檔案,模組或者工具tool時,就不太好辦了。因為Makefile中並沒有相關檔案的資訊,也就是說即使執行make,新加的模組也不會進行編譯。
但是自從有了cmake後就好辦多了。可以直接在CMakeList.txt中把新寫的模組檔案新增進去,然後make就好。因為是基於ceph整個工程的,所以標頭檔案include路徑依照ceph/src為工程根目錄匯入即可。同時,也不太需要關心global連結依賴的問題,直接模仿一下ceph的寫法就好。
先說明一下ceph CMakeList.txt的結構,如下所示。在工程根目錄下有一個總的CMakeList.txt檔案,然後使用add_subdirectory語句層層遞進,從而找到所有的CMakeList的配置。因此,我們在更改ceph原始碼時,只需要修改該模組下的CMakeList.txt即可。
├── ceph-root
│ ├── build
│ │ ├── ...
│ ├── CMakeLists.txt
│ ├── src
│ │ ├── CMakeLists.txt
│ │ ├── tools
│ │ │ ├── CMakeLists.txt
│ │ ├── osd
│ │ │ ├── CMakeLists.txt
│ │ ├── mon
│ │ │ ├── CMakeLists.txt
│ │ │...12345678910111213
比如,我們想增加一個命令列工具,在 src/tools/ 目錄下,新建了一個目錄,嗯,叫demo。這個工程什麼都不做,就使用了boost-pragram_option進行命令列的解析,然後列印引數值。其程式如下:
#include <boost/program_options.hpp>
#include <iostream>
using namespace std;
namespace po = boost::program_options;
int main(int args, char** argv){
try {
po::options_description generic("Generic Options: ");
generic.add_options()
("help", "help message")
("version,v", "print procedure version");
int opt = 5;
po::options_description ha("haha Options: ");
ha.add_options()
("opt", po::value<int>(&opt)->default_value(10), "optimize value");
po::options_description cmdline_options;
cmdline_options.add(generic).add(ha);
po::variables_map vm;
po::store(po::parse_command_line(args, argv, cmdline_options), vm);
po::notify(vm);
if (vm.count("help")){
cout << cmdline_options << endl;
return 1;
}
cout << "vm opt = " << vm["opt"].as<int>() << endl;
cout << "no opt = " << opt << endl;
}
catch(exception& e) {
}
catch(...) {
}
cout << "haha!" << endl;
return 0;12345678910111213141516171819202122232425262728293031323334353637383940
然後再demo/ 目錄下,新建一個CMakeList.txt檔案,只需要在檔案上寫上這麼幾句話:
set(demo test.cc)
add_executable(demo ${demo})
target_link_libraries(demo global
${BLKID_LIBRARIES} ${CMAKE_DL_LIBS})1234
然後在上層目錄的CMakeList.txt中標識demo這個檔案。
...
add_subdirectory(demo)
...123
然後,返回root/build目錄,執行cmake ..,會重新生成一個Makefile,然後執行make demo,就能夠找到 build/bin/demo 這個可執行檔案,執行就會輸出:
@ ./bin/demo --help
Generic Options: :
--help help message
-v [ --version ] print procedure version
haha Options: :
--opt arg (=10) optimize value1234567
按照這個例子,可以引用librados、librbd等庫或者函式,然後就可以依樣畫葫蘆,編譯出自己的tool了
---------------------
作者:hedongho
來源:CSDN
原文:https://blog.csdn.net/hedongho/article/details/79993098
版權宣告:本文為博主原創文章,轉載請附上博文連結!