1. 程式人生 > >使用cmake編譯Ceph簡易教程

使用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
版權宣告:本文為博主原創文章,轉載請附上博文連結!