cmake使用教程(二)-新增庫

saka發表於2018-01-29

【cmake系列使用教程】

cmake使用教程(一)-起步

cmake使用教程(二)-新增庫

cmake使用教程(三)-安裝、測試、系統自檢

cmake使用教程(四)-檔案生成器

cmake使用教程(五)-cpack生成安裝包

cmake使用教程(六)-蛋疼的語法

cmake使用教程(七)-流程和迴圈

cmake使用教程(八)-macro和function

這個系列的文章翻譯自官方cmake教程:cmake tutorial

示例程式地址:github.com/rangaofei/t…

不會僅僅停留在官方教程。本人作為一個安卓開發者,實在是沒有linux c程式開發經驗,望大佬們海涵。教程是在macos下完成,大部分linux我也測試過,有特殊說明的我會標註出來。本教程基於cmake-3.10.2,同時認為你已經安裝好cmake。

構建自己的庫

這個庫將包含我們自己計算一個數字的平方根的計算方法。生成的程式可以使用這個庫,而不是由編譯器提供的標準平方根函式(math.h)。

在本教程中,我們將把庫放到一個名為mathfunction的子目錄中,在工程目錄下新建mathfunction資料夾。這個資料夾中新建CMakeLists.txt檔案,包含以下一行程式碼:

add_library(MathFunctions mysqrt.cxx)
複製程式碼

然後在這個資料夾中建立原始檔mysqrt.cxx,它只有一個名為mysqrt的函式,與編譯器的sqrt函式提供了類似的功能。

為了利用新庫,我們在工程根目錄下的CMakeLists.txt中新增add_subdirectory()來構建我們自己的庫。我們還新增了另一個include目錄,以便MathFunctions / MathFunctions.h可以為函式原型找到標頭檔案,該檔案程式碼如下:

double mysqrt(double x);
複製程式碼

然後建立mysqrt.cxx檔案,內容如下

#include "MathFunctions.h"
#include <stdio.h>

// a hack square root calculation using simple operations
double mysqrt(double x)
{
  if (x <= 0) {
    return 0;
  }

  double result;
  double delta;
  result = x;

  // do ten iterations
  int i;
  for (i = 0; i < 10; ++i) {
    if (result <= 0) {
      result = 0.1;
    }
    delta = x - (result * result);
    result = result + 0.5 * delta / result;
    fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result);
  }
  return result;
}
複製程式碼

最後一個更改是將新庫新增到可執行檔案。根目錄下CMakeLists.txt的最後新增以下程式碼

include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions) 
 
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)
複製程式碼

現在檔案目錄如下

.
├── CMakeLists.txt
├── MathFunctions
│   ├── CMakeLists.txt
│   ├── MathFunctions.h
│   └── mysqrt.cxx
├── TutorialConfig.h.in
└── tutorial.cxx
複製程式碼

構建可選選項

MathFunctions是我們自己構建的庫,有時候我們需要控制這個庫是否應該使用,那麼可以為使用這個庫新增一個開關,在構建大型專案時非常有用。

在專案根目錄下的CMakeLists.txt檔案中新增如下程式碼:

# should we use our own math functions?
option (USE_MYMATH 
        "Use tutorial provided math implementation" ON)
複製程式碼

假如你使用的是CMake GUI,USE_MYMATH預設值是使用者可以根據需要更改。該設定將儲存在快取中,以便使用者在每次執行CMake時生成預設配置。然後我們就可以選擇性的構建和使用mathfunction庫。修改根目錄下CMakeLists.txt:

# add the MathFunctions library?
#
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
  add_subdirectory (MathFunctions)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
 
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})
複製程式碼

這將使用USE_MYMATH的設定來確定是否應該編譯和使用mathfunction庫。注意,使用一個變數(在本例中是EXTRA_LIBS)來設定可選的庫,然後將它們連結到可執行檔案中。這是一種常見的方法,用於保持較大的專案具有許多可選元件。 首先在Configure.h.in檔案中新增以下內容:

#cmakedefine USE_MYMATH
複製程式碼

然後我們就可以使用USE_MYMATH這個變數了,最後修改Tutorial.cxx原始碼如下:

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif
 
int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"%s Version %d.%d\n", argv[0],
            Tutorial_VERSION_MAJOR,
            Tutorial_VERSION_MINOR);
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
 
  double inputValue = atof(argv[1]);
 
#ifdef USE_MYMATH
  double outputValue = mysqrt(inputValue);
#else
  double outputValue = sqrt(inputValue);
#endif
 
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}
複製程式碼

我們編譯執行看以下結果

  1. 使用自定義的庫(USE_MYMATH=ON)
 ~/Desktop/Tutorial/Step2/ ./Tutorial 4
Computing sqrt of 4 to be 2.5
Computing sqrt of 4 to be 2.05
Computing sqrt of 4 to be 2.00061
Computing sqrt of 4 to be 2
Computing sqrt of 4 to be 2
Computing sqrt of 4 to be 2
Computing sqrt of 4 to be 2
Computing sqrt of 4 to be 2
Computing sqrt of 4 to be 2
Computing sqrt of 4 to be 2
The square root of 4 is 2
複製程式碼
  1. 不適用自定義的庫(USE_MYMATH=OFF)
 ~/Desktop/Tutorial/Step2/ ./Tutorial 4
The square root of 4 is 2
複製程式碼

可以看到,這個開關達到了我們需要的效果。

相關文章